/**
 * 
 */
package com.winit.openapi.isp.controller;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.annotation.Resource;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.winit.common.query.Page;
import com.winit.common.query.SearchRequest;
import com.winit.common.query.Searchable;
import com.winit.common.query.Sort;
import com.winit.common.query.Sort.Direction;
import com.winit.common.spi.command.GetByKeyCommand;
import com.winit.common.spi.context.CommandContext;
import com.winit.erp.spi.bpartner.ContractService;
import com.winit.erp.spi.bpartner.command.ContractCommand;
import com.winit.fna.spi.iSPExpenseDetails.ExpenseDetailsService;
import com.winit.fna.spi.iSPExpenseDetails.command.ExpenseDetailsCommand;
import com.winit.fna.spi.iSPExpenseDetails.vo.ExpenseDetails;
import com.winit.gfs.spi.GfsOrderServices;
import com.winit.gfs.spi.vo.GfsOrder;
import com.winit.gfs.spi.vo.GfsOrderDetail;
import com.winit.oms.spi.common.OrderCalculateFeeService;
import com.winit.oms.spi.common.command.WinitProductCalculateFeeCommand;
import com.winit.oms.spi.common.vo.PackageDetail;
import com.winit.oms.spi.common.vo.SalesCalculateFeeResult;
import com.winit.oms.spi.isp.ISPOrderRevenueService;
import com.winit.oms.spi.isp.ISPOrderService;
import com.winit.oms.spi.isp.ISPOrderStepValidateService;
import com.winit.oms.spi.isp.ISPOrderTrackingService;
import com.winit.oms.spi.isp.YanWenOrderService;
import com.winit.oms.spi.isp.command.CommitCheckExOrderCommand;
import com.winit.oms.spi.isp.command.order.ExportISPOrderCommand;
import com.winit.oms.spi.isp.command.order.ISPOrderCreateCommand;
import com.winit.oms.spi.isp.command.order.ISPOrderDeleteCommand;
import com.winit.oms.spi.isp.command.order.ISPOrderSearchCommand;
import com.winit.oms.spi.isp.command.order.ISPOrderSubmmitCommand;
import com.winit.oms.spi.isp.command.order.ISPOrderUpdateCommand;
import com.winit.oms.spi.isp.command.order.ISPOrderValidateCommand;
import com.winit.oms.spi.isp.command.order.ISPOrderVoidCommand;
import com.winit.oms.spi.isp.command.vendor.yanwen.YanWenOrderLibraryCommand;
import com.winit.oms.spi.isp.common.BatchResult;
import com.winit.oms.spi.isp.common.EnumOrderType;
import com.winit.oms.spi.isp.vo.ISPOrder;
import com.winit.oms.spi.isp.vo.ISPOrderException;
import com.winit.oms.spi.isp.vo.ISPOrderLine;
import com.winit.oms.spi.isp.vo.ISPOrderMerchandise;
import com.winit.oms.spi.isp.vo.ISPOrderStatisticsVO;
import com.winit.oms.spi.isp.vo.OrderTrackingVo;
import com.winit.oms.spi.isp.vo.YanWenOrder;
import com.winit.oms.spi.vo.CreateOrderResult;
import com.winit.oms.spi.vo.OrderRevenue;
import com.winit.openapi.constants.ApiConstant;
import com.winit.openapi.constants.ErrorCode;
import com.winit.openapi.controller.BaseController;
import com.winit.openapi.exception.ApiException;
import com.winit.openapi.isp.status.EnumISPOrderStatus;
import com.winit.openapi.model.RequestMsg;
import com.winit.openapi.model.ResponseMsg;
import com.winit.openapi.util.DateUtil;
import com.winit.openapi.util.ValidateUtil;
import com.winit.openapi.util.WinitStringUtils;
import com.winit.pms.spi.winit.WinitProductService;
import com.winit.pms.spi.winit.command.WinitProductQueryCommand;
import com.winit.pms.spi.winit.vo.DeclareGoods;
import com.winit.pms.spi.winit.vo.SalesCalculatorFee;
import com.winit.pms.spi.winit.vo.WinitProduct;

/**
 * isp 订单处理
 * 
 * @author kang.wang 2015-1-5 下午7:52:09
 * @since 1.0
 */
@Controller
@RequestMapping(value = "/isp/order")
public class ISPOrderController extends BaseController {


    private static final Logger logger = LoggerFactory.getLogger(ISPOrderController.class);

    @Resource
    private ISPOrderService             ispOrderService;
    @Resource
    private ContractService             agreementService;
    @Resource
    private ISPOrderStepValidateService iSPOrderStepValidateService;
    @Resource
    private OrderCalculateFeeService    orderCalculateFeeService;
    @Resource
    private YanWenOrderService yanWenOrderService;
    @Resource
    private ExpenseDetailsService expenseDetailsService;
    @Resource
    private ISPOrderRevenueService      iSPOrderRevenueService;
    @Resource
    private ISPOrderTrackingService     ispOrderTrackingService;
    @Resource
    private GfsOrderServices    gfsOrderServices;
    @Resource
    private WinitProductService    winitProductService;
    
    public void setAgreementService(ContractService agreementService) {
        this.agreementService = agreementService;
    }

    /**
     * @param ispOrderService the ispOrderService to set
     */
    public void setIspOrderService(ISPOrderService ispOrderService) {
        this.ispOrderService = ispOrderService;
    }

    /**
     * 创建ISP订单
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/create")
    public String create(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {

        // 效验用户是否是isp业务用户
        checkIspRight();
        Object obj = requestMsg.getData();

        List<ISPOrder> orderList = new ArrayList<ISPOrder>();

        if (obj instanceof JSONObject) {
            JSONObject json = (JSONObject) obj;
            // 校验参数
            validCreateISPOrder(json);
            ISPOrder ispOrder = buildISPOrder(json);
            orderList.add(ispOrder);
        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }

        // 组装command
        ISPOrderCreateCommand command = new ISPOrderCreateCommand();
        command.setCtx(CommandContext.getContext());
        command.setOrderList(orderList);

        // 调用接口创建订单
        CreateOrderResult result = ispOrderService.createISPOrder(command);

        if (result.isSuccess()) {
            // 返回订单号
            Map<String, String> data = new HashMap<String, String>();
            data.put("orderNo", result.getOrderNo());
            responseMsg.setData(data);
        } else {
            responseMsg.setData(result.getMessageList());
            throw new ApiException(ErrorCode.VALIDTE_ORDER_FAILED);
        }
        return SUCCESS;
    }
    
    /**
     * 创建ISP订单
     * 返回trackingNo
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/createOrder")
    public String createOrder(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {

        // 效验用户是否是isp业务用户
        checkIspRight();
        Object obj = requestMsg.getData();

        List<ISPOrder> orderList = new ArrayList<ISPOrder>();

        if (obj instanceof JSONObject) {
            JSONObject json = (JSONObject) obj;
            // 校验参数
            validCreateISPOrder(json);
            ISPOrder ispOrder = buildISPOrder(json);
            orderList.add(ispOrder);
        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }

        // 组装command
        ISPOrderCreateCommand command = new ISPOrderCreateCommand();
        command.setCtx(CommandContext.getContext());
        command.setOrderList(orderList);

        // 调用接口创建订单
        CreateOrderResult result = ispOrderService.createISPOrder(command);

        if (result.isSuccess()) {
            // 返回订单号
            Map<String, String> data = new HashMap<String, String>();
            data.put("orderNo", result.getOrderNo());
            data.put("trackingNo", result.getTrackingNo());
            responseMsg.setData(data);
        } else {
            responseMsg.setData(result.getMessageList());
            throw new ApiException(ErrorCode.VALIDTE_ORDER_FAILED);
        }
        return SUCCESS;
    }
    
    /**
     * 校验平台同步下ISP订单
     * 返回返回预估费用
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/checkOrder")
    public String checkOrder(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {

        Object obj = requestMsg.getData();

        List<ISPOrder> orderList = new ArrayList<ISPOrder>();

        if (obj instanceof JSONObject) {
            JSONObject json = (JSONObject) obj;
            // 校验参数
            validCreateISPOrder(json);
            ISPOrder ispOrder = buildISPOrder(json);
            orderList.add(ispOrder);
        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }

        // 组装command
        ISPOrderCreateCommand command = new ISPOrderCreateCommand();
        command.setCtx(CommandContext.getContext());
        command.setOrderList(orderList);

        // 调用接口创建订单
        BigDecimal shippingFee = ispOrderService.checkOrder(command);

        if (shippingFee != null) {
            // 返回订单号
            Map<String, BigDecimal> data = new HashMap<String, BigDecimal>();
            data.put("shippingFee",shippingFee);
            responseMsg.setData(data);
        } else {
            throw new ApiException(ErrorCode.VALIDTE_ORDER_FAILED);
        }
        return SUCCESS;
    }

    /**
     * 费用预估
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/chargesEstimate")
    public String chargesEstimate(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        // 效验用户是否是isp业务用户
        checkIspRight();
        Object obj = requestMsg.getData();
        if (obj instanceof JSONObject) {
            JSONObject json = (JSONObject) obj;
            // 校验参数
            valiChargesParms(json);
            WinitProductCalculateFeeCommand command = buildChargesEstimate(json);
            // 计算预估费用
            SalesCalculateFeeResult result = orderCalculateFeeService.calculateFee(command);
            Map<String, Object> resultMap = new HashMap<String, Object>();
            Map<String, Object> dataMap = null;
            List<Map<String, Object>> chargesListMap = new ArrayList<Map<String, Object>>();
            if (result.getFeeList().size() > 0) {
                for (SalesCalculatorFee sf : result.getFeeList()) {
                    if (sf.getResultFee().compareTo(new BigDecimal(0)) == 0) {
                        logger.info("当前费用项的费用为0,不线上到前台页面,费用项编码:{},费用项名称:{}",
                            new Object[] {sf.getSalesChangeItemName(), sf.getSalesChangeItemName() });
                        continue;
                    }
                    dataMap = new HashMap<String, Object>();
                    dataMap.put("chargesName", sf.getSalesChangeItemName());
                    dataMap.put("amount", sf.getResultFee().setScale(2, BigDecimal.ROUND_HALF_UP)); // 保留2位小数
                    dataMap.put("currencySystem", sf.getCurrency());
                    chargesListMap.add(dataMap);
                }
            }
            resultMap.put("chargesList", chargesListMap);
            resultMap.put("total", result.getTotalFeeCNY());// 保留2位小数
            responseMsg.setData(resultMap);

        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }
        return SUCCESS;
    }

    /**
     * 批量创建ISP订单
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/batchImport")
    public String batchImport(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        // 效验用户是否是isp业务用户
        checkIspRight();
        Object obj = requestMsg.getData();

        List<ISPOrder> orderList = new ArrayList<ISPOrder>();
        if (obj instanceof JSONArray) {
            JSONArray jsonarr = (JSONArray) obj;
            if (jsonarr.size() > 0) {
                for (int i = 0; i < jsonarr.size(); i++) {
                    JSONObject json = jsonarr.getJSONObject(i);
                    // 校验参数
                    validBatchImportISPOrder(json);
                    ISPOrder ispOrder = buildISPOrder(json);
                    orderList.add(ispOrder);
                }
            } else {
                throw new ApiException(ErrorCode.ORDER_NOT_NULL);
            }
        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }
        // 组装command
        ISPOrderCreateCommand command = new ISPOrderCreateCommand();
        command.setCtx(CommandContext.getContext());
        command.setOrderList(orderList);

        // 调用接口创建订单
        BatchResult result = ispOrderService.batchCreateISPOrder(command);

        Map<String, Object> data = new HashMap<String, Object>();
        data.put("successCount", result.getSuccess());
        data.put("failedCount", result.getFailed());
        responseMsg.setData(data);

        return SUCCESS;
    }

    /**
     * 批量导出ISP订单
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/batchExport")
    public String batchExport(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        // 效验用户是否是isp业务用户
        checkIspRight();
        Object obj = requestMsg.getData();

        ExportISPOrderCommand command = null;

        if (obj instanceof JSONObject) {
            JSONObject json = (JSONObject) obj;
            validSearchISPOrder(json);
            command = buildSearchOrderCommand(json);
            Searchable searchable = buildExportPageParams(json);
            command.setSearchable(searchable);
        } else if (obj == null || StringUtils.isBlank(obj.toString())) {
            Searchable searchable = buildExportPageParams(null);
            command = new ExportISPOrderCommand();
            command.setSearchable(searchable);
        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }
        command.setCtx(CommandContext.getContext());
        Page<ISPOrder> pagelist = ispOrderService.exportISPorder(command);

        if (pagelist != null) {
            List<Map<String, Object>> datalist = buildReturnISPOrderOutList(pagelist.getContent(),
                ApiConstant.ISP_ORDER_TPYE_EX);
            Map<String, Object> pageMap = new HashMap<String, Object>();
            pageMap.put("pageNo", pagelist.getPageable().getPageNumber());
            pageMap.put("pageSize", pagelist.getPageable().getPageSize());
            pageMap.put("totalCount", pagelist.getTotalElements());

            Map<String, Object> data = new HashMap<String, Object>();
            data.put("list", datalist);
            data.put("pageParams", pageMap);
            responseMsg.setData(data);
        }

        return SUCCESS;
    }

    /**
     * 修改ISP订单
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/update")
    public String update(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        // 效验用户是否是isp业务用户
        checkIspRight();
        Object obj = requestMsg.getData();

        List<ISPOrder> orderList = new ArrayList<ISPOrder>();

        Map<String, Object> data = new HashMap<String, Object>();
        if (obj instanceof JSONObject) {
            JSONObject json = (JSONObject) obj;
            // 校验参数
            validUpdateISPOrder(json);
            ISPOrder ispOrder = buildISPOrder(json);
            orderList.add(ispOrder);

            ISPOrderUpdateCommand command = new ISPOrderUpdateCommand();
            command.setOrderList(orderList);
            command.setCtx(CommandContext.getContext());
            // 单个订单修改以异常的方式返回错误信息
            ispOrderService.updateISPOrder(command);
            data.put("successCount", 1);
            data.put("failedCount", 0);
            responseMsg.setData(data);
        } else if (obj instanceof JSONArray) {
            JSONArray arr = (JSONArray) obj;
            for (int i = 0; i < arr.size(); i++) {
                JSONObject json = arr.getJSONObject(i);
                // 校验参数
                validUpdateISPOrder(json);
                ISPOrder ispOrder = buildISPOrder(json);
                orderList.add(ispOrder);
            }

            // 组装command
            ISPOrderSubmmitCommand command = new ISPOrderSubmmitCommand();

            command.setOrderList(orderList);
            command.setCtx(CommandContext.getContext());
            // 批量修改只返回成功数量，错误数量，不返回错误信息
            BatchResult result = ispOrderService.batchSubmmitISPOrder(command);

            data.put("successCount", result.getSuccess());
            data.put("failedCount", result.getFailed());
            responseMsg.setData(data);
        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }

        return SUCCESS;
    }

    /**
     * 作废ISP订单
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/disable")
    public String disable(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        // 效验用户是否是isp业务用户
        checkIspRight();
        Object obj = requestMsg.getData();

        List<String> orderList = new ArrayList<String>();

        if (obj instanceof JSONObject) {
            JSONObject json = (JSONObject) obj;
            // 校验参数
            validOrderNo(json);
            orderList.add(json.getString("orderNo"));
        } else if (obj instanceof JSONArray) {
            JSONArray arr = (JSONArray) obj;
            for (int i = 0; i < arr.size(); i++) {
                JSONObject json = arr.getJSONObject(i);
                // 校验参数
                validOrderNo(json);
                orderList.add(json.getString("orderNo"));
            }
        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }

        // 组装command
        ISPOrderVoidCommand command = new ISPOrderVoidCommand();
        command.setCtx(CommandContext.getContext());

        command.setOrderNoList(orderList);
        // 调用接口作废订单
        BatchResult result = ispOrderService.voidISPOrder(command);

        Map<String, Object> data = new HashMap<String, Object>();
        data.put("successCount", result.getSuccess());
        data.put("failedCount", result.getFailed());
        responseMsg.setData(data);

        return SUCCESS;
    }
    /**
     * 删除ISP订单
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/deleteISPOrder")
    public String deleteISPOrder(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        // 效验用户是否是isp业务用户
        checkIspRight();
        Object obj = requestMsg.getData();

        List<String> orderList = new ArrayList<String>();

        if (obj instanceof JSONObject) {
            JSONObject json = (JSONObject) obj;
            // 校验参数
            validOrderNo(json);
            orderList.add(json.getString("orderNo"));
        } else if (obj instanceof JSONArray) {
            JSONArray arr = (JSONArray) obj;
            for (int i = 0; i < arr.size(); i++) {
                JSONObject json = arr.getJSONObject(i);
                // 校验参数
                validOrderNo(json);
                orderList.add(json.getString("orderNo"));
            }
        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }

        // 组装command
        ISPOrderDeleteCommand command = new ISPOrderDeleteCommand();
        command.setCtx(CommandContext.getContext());

        command.setOrderNoList(orderList);
        // 调用接口作废订单
        BatchResult result = ispOrderService.deleteISPOrder(command);

        Map<String, Object> data = new HashMap<String, Object>();
        data.put("successCount", result.getSuccess());
        data.put("failedCount", result.getFailed());
        responseMsg.setData(data);

        return SUCCESS;
    }
    
    
    

    /**
     * 查询订单详情
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/query")
    public String query(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        // 效验用户是否是isp业务用户
        checkIspRight();
        Object obj = requestMsg.getData();

        GetByKeyCommand<String> command = new GetByKeyCommand<String>();
        if (obj instanceof JSONObject) {
            JSONObject json = (JSONObject) obj;
            validOrderNo(json);
            command.setSearchKey(json.getString("orderNo"));
        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }
        command.setCtx(CommandContext.getContext());
        // 调用接口查询订单
        ISPOrder order = ispOrderService.getISPOrderByNo(command);
        if (order != null) {
            Map<String, Object> map = buildReturnISPOrderInfo(order, ApiConstant.ISP_ORDER_TPYE_NORMAL);
            // 从GFS已发货订单，显示ebay订单商品相关信息
            if(ApiConstant.API_SOURCE_GFS.equals(order.getSource()) && !"PD".equals(order.getStatus())){
                GetByKeyCommand<String> getByKeyCommand = new GetByKeyCommand<String>();
                getByKeyCommand.setSearchKey(order.getOrderNo());
                GfsOrder gfsOrder = gfsOrderServices.getGfsOrderByOrderNo(getByKeyCommand);
                if(gfsOrder != null){
                    Map<String, Object> data = buildEditOrder(gfsOrder);
                    map.put("gfsOrder", data);
                }
            }
            responseMsg.setData(map);
        } else {
            throw new ApiException(ErrorCode.FIELD_ISPORDERNO_NOT_EXIST);
        }
        return SUCCESS;
    }

    /**
     * 查询订单列表
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/list")
    public String list(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        // 效验用户是否是isp业务用户
        checkIspRight();
        Object obj = requestMsg.getData();

        ISPOrderSearchCommand command = null;

        if (obj instanceof JSONObject) {
            JSONObject json = (JSONObject) obj;
            validSearchISPOrder(json);
            command = buildSearchOrderCommand(json);
            Searchable searchable = buildSearchPageParams(json);
            command.setSearchable(searchable);
        } else if (obj == null || StringUtils.isBlank(obj.toString())) {
            Searchable searchable = buildSearchPageParams(null);
            command = new ISPOrderSearchCommand();
            command.setSearchable(searchable);
        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }
        command.setCtx(CommandContext.getContext());

        // 调用接口分页查询订单
        Page<ISPOrder> pagelist = ispOrderService.getISPOrderList(command);
        if (pagelist != null) {
            List<Map<String, Object>> datalist = buildReturnISPOrderList(pagelist.getContent(),
                ApiConstant.ISP_ORDER_TPYE_NORMAL);

            Map<String, Object> pageMap = new HashMap<String, Object>();
            pageMap.put("pageNo", pagelist.getPageable().getPageNumber());
            pageMap.put("pageSize", pagelist.getPageable().getPageSize());
            pageMap.put("totalCount", pagelist.getTotalElements());

            Map<String, Object> data = new HashMap<String, Object>();
            data.put("list", datalist);
            data.put("pageParams", pageMap);
            responseMsg.setData(data);
        }
        return SUCCESS;
    }

    /**
     * 查询ISP异常订单列表
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/exceptionList")
    public String exceptionList(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        // 效验用户是否是isp业务用户
        checkIspRight();
        Object obj = requestMsg.getData();

        ISPOrderSearchCommand command = null;

        if (obj instanceof JSONObject) {
            JSONObject json = (JSONObject) obj;
            validSearchISPOrder(json);
            command = buildSearchOrderCommand(json);
            Searchable searchable = buildSearchPageParams(json);
            command.setSearchable(searchable);
        } else if (obj == null || StringUtils.isBlank(obj.toString())) {
            Searchable searchable = buildSearchPageParams(null);
            command = new ISPOrderSearchCommand();
            command.setSearchable(searchable);
        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }
        command.setCtx(CommandContext.getContext());
        // 调用接口查询异常订单
        Page<ISPOrder> pagelist = ispOrderService.findAbnormalISPOrder(command);
        if (pagelist != null) {
            List<Map<String, Object>> datalist = buildReturnISPOrderList(pagelist.getContent(),
                ApiConstant.ISP_ORDER_TPYE_EX);

            Map<String, Object> pageMap = new HashMap<String, Object>();
            pageMap.put("pageNo", pagelist.getPageable().getPageNumber());
            pageMap.put("pageSize", pagelist.getPageable().getPageSize());
            pageMap.put("totalCount", pagelist.getTotalElements());

            Map<String, Object> data = new HashMap<String, Object>();
            data.put("list", datalist);
            data.put("pageParams", pageMap);
            responseMsg.setData(data);
        }

        return SUCCESS;
    }

    /**
     * 导出ISP异常订单列表
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/exportExceptionList")
    public String exportExceptionList(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        // 效验用户是否是isp业务用户
        checkIspRight();
        Object obj = requestMsg.getData();

        ISPOrderSearchCommand command = null;

        if (obj instanceof JSONObject) {
            JSONObject json = (JSONObject) obj;
            validSearchISPOrder(json);
            command = buildSearchOrderCommand(json);
            Searchable searchable = buildExportPageParams(json);
            command.setSearchable(searchable);
        } else if (obj == null || StringUtils.isBlank(obj.toString())) {
            Searchable searchable = buildExportPageParams(null);
            command = new ISPOrderSearchCommand();
            command.setSearchable(searchable);
        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }
        command.setCtx(CommandContext.getContext());
        // 调用接口查询异常订单
        Page<ISPOrder> pagelist = ispOrderService.findAbnormalISPOrder(command);
        if (pagelist != null) {
            List<Map<String, Object>> datalist = buildReturnISPOrderList(pagelist.getContent(),
                ApiConstant.ISP_ORDER_TPYE_EX);

            Map<String, Object> pageMap = new HashMap<String, Object>();
            pageMap.put("pageNo", pagelist.getPageable().getPageNumber());
            pageMap.put("pageSize", pagelist.getPageable().getPageSize());
            pageMap.put("totalCount", pagelist.getTotalElements());

            Map<String, Object> data = new HashMap<String, Object>();
            data.put("list", datalist);
            data.put("pageParams", pageMap);
            responseMsg.setData(data);
        }

        return SUCCESS;
    }

    /**
     * 暂存ISP订单
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/save")
    public String save(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        // 效验用户是否是isp业务用户
        checkIspRight();
        Object obj = requestMsg.getData();

        List<ISPOrder> orderList = new ArrayList<ISPOrder>();

        if (obj instanceof JSONObject) {
            JSONObject json = (JSONObject) obj;
            // 校验参数
            validCreateISPOrder(json);
            ISPOrder ispOrder = buildISPOrder(json);
            orderList.add(ispOrder);
        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }
        // 组装command
        ISPOrderCreateCommand command = new ISPOrderCreateCommand();
        command.setCtx(CommandContext.getContext());
        command.setOrderList(orderList);

        // 调用接口创建订单
        CreateOrderResult result = ispOrderService.saveISPOrderTemporary(command);
        if (result.isSuccess()) {
            // 返回订单号
            Map<String, String> data = new HashMap<String, String>();
            data.put("orderNo", result.getOrderNo());
            responseMsg.setData(data);
        } else {
            responseMsg.setData(result.getMessageList());
            throw new ApiException(ErrorCode.VALIDTE_ORDER_FAILED);
        }
        return SUCCESS;
    }
    /**
     * 根据订单号查询应收费用详情
     * TODO Add comments here.
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value="getOrderRevenue")
    public String getOrderRevenue(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg){
        Object obj = requestMsg.getData();
        String orderNo ="";
        if (obj instanceof JSONObject) {
            JSONObject json = (JSONObject) obj;
            // 校验参数
            ValidateUtil.validNotNull(json, "orderNo");
            ValidateUtil.validMaxLength(json, "orderNo", 60);
            orderNo = json.getString("orderNo");
        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }
        
        GetByKeyCommand<String> command = new GetByKeyCommand<String>();
        command.setSearchKey(orderNo);
        ISPOrder order = ispOrderService.getISPOrderByNo(command);
        if(order==null){
            responseMsg.setMsg("该订单号不存在");
            return ERROR;
        }
        List<OrderRevenue> revenueList = iSPOrderRevenueService.queryRevenueByOrderNo(command);
        List<Map<String, Object>> list = new ArrayList<Map<String,Object>>();
        Map<String, Object> data = new HashMap<String, Object>();
//        data.put("orderNo", order.getOrderNo());
//        data.put("orderStatus", order.getStatus());
        if(revenueList!=null){
            BigDecimal totalAmount = new BigDecimal(0);
            for (OrderRevenue orderRevenue : revenueList) {
                // 金额为0的不显示
                if(orderRevenue.getAmount().compareTo(BigDecimal.valueOf(0.0)) <= 0){
                    continue;
                }
                Map<String, Object> map = new HashMap<String, Object>();
//                map.put("orderDate", orderRevenue.getOrderDate());
//                map.put("bpartnerId", orderRevenue.getBpartnerId());
//                map.put("bpartnerName", orderRevenue.getBpartnerName());
//                map.put("winitProductCode", orderRevenue.getWinitProductCode());
                map.put("currencyCode", orderRevenue.getCurrencyCode());
//                map.put("exRate", orderRevenue.getExRate());
//                map.put("standardCurrencyCode", orderRevenue.getStandardCurrencyCode());
//                map.put("revenueNo", orderRevenue.getRevenueNo());
                map.put("chargeName", orderRevenue.getChargeName());
//                map.put("unitPrice", orderRevenue.getUnitPrice());
//                map.put("chargeWeight", orderRevenue.getChargeWeight());
                map.put("amount", orderRevenue.getAmount());
//                map.put("acctDate", orderRevenue.getAcctDate());
//                map.put("status", orderRevenue.getStatus());
                list.add(map);
                
                totalAmount = totalAmount.add(orderRevenue.getAmount().multiply(orderRevenue.getExRate()));
            }
            //总额（USD）= 金额总和(交易金额*汇率)
            data.put("totalAmount", totalAmount.setScale(2, BigDecimal.ROUND_HALF_UP));
            data.put("standardCurrencyCode", "USD");
        }else{
            responseMsg.setMsg("该订单未产生费用");
            return ERROR;
        }
        data.put("chargeItemList", list);
        
        //返回核实重量、核实长、核实宽、核实高
        ISPOrderLine ispOrderLine = order.getOrderLineList().get(0);
        data.put("cfmLength", ispOrderLine.getCfmLength());
        data.put("cfmWidth", ispOrderLine.getCfmWidth());
        data.put("cfmHeight", ispOrderLine.getCfmHeight());
        data.put("cfmGrossWeight", ispOrderLine.getCfmGrossWeight());
        
        //返回ebay总申报价值
        BigDecimal totalEbayItemPriceAmount = new BigDecimal(0);
        List<ISPOrderMerchandise> merchandiseList = order.getOrderLineList().get(0).getMerchandiseList();
        if(CollectionUtils.isNotEmpty(merchandiseList)){
            for(ISPOrderMerchandise merchandise : merchandiseList){
                BigDecimal ebayItemPrice = merchandise.getEbayItemPrice();
                BigDecimal quantity = BigDecimal.valueOf(merchandise.getMerchandiseQuantity());
                totalEbayItemPriceAmount = totalEbayItemPriceAmount.add(ebayItemPrice.multiply(quantity));
            }
        }
        if(totalEbayItemPriceAmount.compareTo(BigDecimal.valueOf(0.0)) > 0){
            data.put("totalEbayItemPriceAmount", totalEbayItemPriceAmount);
        }
        
        responseMsg.setData(data);
        return SUCCESS;
    }
    /**
     * 
     * 查询ISP订单费用
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/chargeList")
    public String chargeList(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        // 效验用户是否是isp业务用户
        checkIspRight();
        Object obj = requestMsg.getData();
        
        String orderNo = null;
        String trackingNo = null;
        CommandContext ctx = CommandContext.getContext();

        if (obj instanceof JSONObject) {
            JSONObject json = (JSONObject) obj;
            ValidateUtil.validMaxLength(json, "orderNo", 30);
            ValidateUtil.validMaxLength(json, "trackingNo", 100);
            
            if(json.containsKey("orderNo")){
                orderNo = json.getString("orderNo");
            }
            if(json.containsKey("trackingNo")){
                trackingNo = json.getString("trackingNo");
            }
            
            if(StringUtils.isNotBlank(orderNo)){
                GetByKeyCommand<String> command = new GetByKeyCommand<String>();
                command.setCtx(ctx);
                command.setSearchKey(orderNo);
                ISPOrder ispOrder = ispOrderService.getISPOrderByNo(command);
                // 校验订单是否存在
                if(ispOrder == null){
                    throw new ApiException(ErrorCode.ORDER_NO_NOT_EXSIT, orderNo);
                // 校验订单号与跟踪号是否匹配
                } else if (StringUtils.isNotBlank(trackingNo) && ispOrder.getOrderLineList().size() > 0
                           && !ispOrder.getOrderLineList().get(0).getExpressno().equals(trackingNo)) {
                    throw new ApiException(ErrorCode.ORDER_NO_AND_TRACKING_NO_NOT_MATCH, orderNo, trackingNo);
                }
            }else if(StringUtils.isNotBlank(trackingNo)){
                // 根据包裹跟踪号查询订单号
                ISPOrderSearchCommand command = new ISPOrderSearchCommand();
                Searchable search = SearchRequest.newSearchable();
                search.setPage(0, Integer.MAX_VALUE);
                command.setSearchable(search);
                command.setCtx(ctx);
                command.setExpressNo(trackingNo);
                Page<ISPOrder> page = ispOrderService.getISPOrderList(command);
                if(page == null){
                    throw new ApiException(ErrorCode.TRACKING_NO_NOT_EXSIT, trackingNo);
                }
                List<ISPOrder> ispOrderList = page.getContent();
                if(CollectionUtils.isEmpty(ispOrderList)){
                    throw new ApiException(ErrorCode.TRACKING_NO_NOT_EXSIT, trackingNo);
                }
                orderNo = ispOrderList.get(0).getOrderNo();
            }else{
                // 订单号和跟踪号不能都为空
                throw new ApiException(ErrorCode.ORDER_NO_AND_TRACKING_NO_BOTH_NULL);
            }
        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }
        
        // TODO 调用FNA查询费用列表
        ExpenseDetailsCommand command = new ExpenseDetailsCommand();
        command.setCtx(ctx);
        command.setDocumentNo(orderNo);
        List<ExpenseDetails> expenseDetailsList = expenseDetailsService.queryExpenseDetails(command);
        
        if(CollectionUtils.isNotEmpty(expenseDetailsList)){
            Map<String, Object> data = new HashMap<String,Object>();
            List<Map<String, Object>> chargeList = new ArrayList<Map<String, Object>>();
            Map<String, Object> map = null;
            for(ExpenseDetails expenseDetails:expenseDetailsList){
                map = new HashMap<String,Object>();
                if(expenseDetails == expenseDetailsList.get(0)){
                    data.put("orderNo", expenseDetails.getDocumentNo());//订单号
                    data.put("dateInvoiced", expenseDetails.getDateInvoiced());//记账日期
                    data.put("warehouseName", expenseDetails.getWarehouseName());//验货仓
                    data.put("productName", expenseDetails.getProductName());//winit产品
                    data.put("country", expenseDetails.getCountry());//买家国家
                    data.put("orderDate", expenseDetails.getOrderDate());//下单日期
                    data.put("confirmWeight", expenseDetails.getTotalWeight());//核实重量
                    data.put("declareWeight", expenseDetails.getWeight());//申报重量
                    data.put("confirmVolume", expenseDetails.getTotalVolume());//核实体积
                    data.put("trackingNo", expenseDetails.getExpressno());//包裹跟踪号
                    data.put("totalCharges", expenseDetails.getTollSum());//收费总额
                }
                
                map.put("currencyCode", expenseDetails.getIsoCode());//币种
                map.put("convertedDollars", expenseDetails.getInvoiceAmt());//折美元
                map.put("originCurrAmount", expenseDetails.getTrxAmt());//原币金额
                map.put("conversionRate", expenseDetails.getConversionRate());//汇率
                map.put("chargeName", expenseDetails.getExpenseName());//费用名称
                
                chargeList.add(map);
            }
            data.put("chargeList", chargeList);
            responseMsg.setData(data);
        }
        

        return SUCCESS;
    }
    
    /**
     * 
     * 统计订单数据
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/getOrderStatisticsList")
    public String getOrderStatisticsList(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        Object obj = requestMsg.getData();
        CommandContext ctx = CommandContext.getContext();
        if (obj instanceof JSONObject) {
            JSONObject json = (JSONObject) obj;
            // 校验参数
            ValidateUtil.validNotNull(json, "dateFrom");
            ValidateUtil.validDateString(json, "dateFrom", DateUtil.SIMPLE_DATE_STRING);
            ValidateUtil.validNotNull(json, "dateTo");
            ValidateUtil.validDateString(json, "dateTo", DateUtil.SIMPLE_DATE_STRING);
            
            ISPOrderSearchCommand command =  new ISPOrderSearchCommand();
            command.setCtx(ctx);
            command.setBpartnerId(Integer.valueOf(ctx.getUserId()));
            String dateFrom = json.getString("dateFrom") + " 00:00:00";
            String dateTo = json.getString("dateTo") + " 23:59:59";
            command.setDateFrom(DateUtil.parse2Date(dateFrom, DateUtil.FULL_DATE_STRING));
            command.setDateTo(DateUtil.parse2Date(dateTo, DateUtil.FULL_DATE_STRING));
            // productCatalogLv2
            if (json.containsKey("productCatalogLv2")) {
                command.setProductCatalogLv2(json.getString("productCatalogLv2"));
            }
            List<ISPOrderStatisticsVO> orderStatisticsList = ispOrderService.getISPOrderStatisticsList(command);
            
            List<Map<String,Object>> datalist = new ArrayList<Map<String,Object>>();
            Map<String,Object> map = null;
            if(orderStatisticsList != null){
                for(ISPOrderStatisticsVO statisticsVo : orderStatisticsList){
                    map = new HashMap<String,Object>();
                    map.put("productCode", statisticsVo.getWinitProductCode());
                    if(StringUtils.isNotEmpty(statisticsVo.getWinitProductCode())){
                        //设置翻译信息
                        WinitProductQueryCommand queryCommand = new WinitProductQueryCommand();
                        queryCommand.setCode(statisticsVo.getWinitProductCode());
                        queryCommand.setCtx(command.getCtx());
                        WinitProduct winitProduct = winitProductService.queryProduct(queryCommand);
                        if(winitProduct !=null){
                            map.put("productName", winitProduct.getName());
                        }
                    } else {
                        map.put("productName", "");
                    }
                    map.put("totalCount", statisticsVo.getOrderCount());
                    map.put("wfdCount", statisticsVo.getSubmittedCount());
                    map.put("wfrCount", statisticsVo.getConfirmDeliveryCount());
                    map.put("cfsCount", statisticsVo.getInboundedCount());
                    map.put("wfiCount", statisticsVo.getReceivedAndInspectedCount());
                    map.put("pcCount", statisticsVo.getPackedCount());
                    map.put("aoCount", statisticsVo.getOutboundedCount());
                    map.put("hpoCount", statisticsVo.getUntrackedOrderOutboundedCount());
                    map.put("dliCount", statisticsVo.getDeliveringCount());
                    map.put("dlcCount", statisticsVo.getDeliveredCount());
                    map.put("pufCount", statisticsVo.getPickupFailedCount());
                    map.put("exCount", statisticsVo.getExceptionCount());
                    map.put("voidCount", statisticsVo.getVoidCount());
                    datalist.add(map);
                }
            }
            
            Map<String, Object> data = new HashMap<String, Object>();
            data.put("list", datalist);
            responseMsg.setData(data);
            
        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }
        
        return SUCCESS;
    }
    
    
    // 费用预估参数组装
    private WinitProductCalculateFeeCommand buildChargesEstimate(JSONObject json) {
        WinitProductCalculateFeeCommand command = new WinitProductCalculateFeeCommand();
        if (json.containsKey("winitProductCode")) {
            command.setWinitProductCode(json.getString("winitProductCode".trim()));
        }
        if (json.containsKey("warehouseCode")) {
            command.setWarehouseCode(json.getString("warehouseCode".trim()));
        }
        if (json.containsKey("startCountryCode")) {
            command.setStartCountryCode(json.getString("startCountryCode".trim()));
        }
        if (json.containsKey("startPostCode")) {
            command.setStartPostCode(json.getString("startPostCode".trim()));
        }
        if (json.containsKey("endCountryCode")) {
            command.setEndCountryCode(json.getString("endCountryCode".trim()));
        }
        if (json.containsKey("endPostCode")) {
            command.setEndPostCode(json.getString("endPostCode".trim()));
        }
        if (json.containsKey("dispatchType")) {
            command.setDispatchType(json.getString("dispatchType".trim()));
        }
        List<PackageDetail> packageDetailList = new ArrayList<PackageDetail>();
        List<DeclareGoods> declareGoodsList = new ArrayList<DeclareGoods>();
        if (json.containsKey("listPackage")) {
            JSONArray packageList = json.getJSONArray("listPackage");
            for (Object obj : packageList) {
                JSONObject pack = (JSONObject) obj;
                PackageDetail packageDetail = new PackageDetail();
                if (pack.containsKey("length")) {
                    packageDetail.setLength(pack.getBigDecimal("length"));
                }
                if (pack.containsKey("width")) {
                    packageDetail.setWidth(pack.getBigDecimal("width"));
                }
                if (pack.containsKey("height")) {
                    packageDetail.setHeight(pack.getBigDecimal("height"));
                }
                if (pack.containsKey("weight")) {
                    packageDetail.setWeight(pack.getBigDecimal("weight"));
                }
                packageDetailList.add(packageDetail);
                
                JSONArray merchandiseList = pack.getJSONArray("merchandiseList");
                for(Object o : merchandiseList){
                    JSONObject mer = (JSONObject) o;
                    DeclareGoods good = new DeclareGoods();
                    Long merchandiseQuantity = 1L;
                    if (mer.containsKey("merchandiseQuantity")) {
                        merchandiseQuantity  = mer.getLong("merchandiseQuantity");
                    }
                    good.setDeclareValueTotal(mer.getBigDecimal("declaredValue").multiply(new BigDecimal(merchandiseQuantity)));
                    declareGoodsList.add(good);
                }
            }
        }
        command.setPackageDetailList(packageDetailList);
        command.setDeclareGoodsList(declareGoodsList);
        return command;
    }

    private ISPOrder buildISPOrder(JSONObject json) {
        ISPOrder ispOrder = new ISPOrder();

        /**************************** ispOrder ***********************/
        if (json.containsKey("isAllowRepeat")) {
            ispOrder.setIsAllowRepeat(StringUtils.trim(json.getString("isAllowRepeat")));
        }
        if (json.containsKey("orderNo")) {
            ispOrder.setOrderNo(StringUtils.trim(json.getString("orderNo")));
        }
        if (json.containsKey("oldOrderNo")) {
            ispOrder.setOldOrderNo(StringUtils.trim(json.getString("oldOrderNo")));
        }
        if (json.containsKey("refNo")) {
            ispOrder.setSellerOrderNo(StringUtils.trim(json.getString("refNo")));
        }
        if (json.containsKey("winitProductCode")) {
            ispOrder.setWinitProductCode(StringUtils.trim(json.getString("winitProductCode")));
        }
        if (json.containsKey("warehouseCode")) {
            ispOrder.setWarehouseCode(StringUtils.trim(json.getString("warehouseCode")));
        }
        if (json.containsKey("warehouseName")) {
            ispOrder.setWarehouseName(StringUtils.trim(json.getString("warehouseName")));
        }
        if (json.containsKey("warehouseID")) {
            ispOrder.setWarehouseID(json.getLong("warehouseID"));
        }
        if (json.containsKey("dispatchType")) {
            ispOrder.setDispatchType(json.getString("dispatchType"));
        }
        /**************************** buyer ***************************/
        if (json.containsKey("buyerName")) {
            ispOrder.setBuyerFullname(WinitStringUtils.removeSpecialChars(json.getString("buyerName")));
        }
        if (json.containsKey("buyerEmail")) {
            ispOrder.setBuyerEmail(WinitStringUtils.removeSpecialChars(json.getString("buyerEmail")));
        }
        if (json.containsKey("buyerZipCode")) {
            ispOrder.setBuyerPostcode(WinitStringUtils.removeSpecialChars(json.getString("buyerZipCode")));
        }
        if (json.containsKey("buyerCountry")) {
            ispOrder.setBuyerCountry(json.getString("buyerCountry"));
        }
        if (json.containsKey("buyerContactNo")) {
            if(StringUtils.isBlank(json.getString("buyerContactNo"))){
                ispOrder.setBuyerContactNumber("-");
            }else{
                if("Invalid Request".equals(json.getString("buyerContactNo"))){
                    ispOrder.setBuyerContactNumber("-");
                }else{
                    ispOrder.setBuyerContactNumber(WinitStringUtils.removeSpecialChars(json.getString("buyerContactNo")));
                }
            }
        }
        if (json.containsKey("buyerState")) {
            if(StringUtils.isBlank(json.getString("buyerState"))){
                ispOrder.setBuyerState("-");
            }else{
                ispOrder.setBuyerState(WinitStringUtils.removeSpecialChars(json.getString("buyerState")));
            }
        }
        if (json.containsKey("buyerCity")) {
            if(StringUtils.isBlank(json.getString("buyerCity"))){
                ispOrder.setBuyerCity("-");
            }else{
                ispOrder.setBuyerCity(WinitStringUtils.removeSpecialChars(json.getString("buyerCity")));
            }
        }
        if (json.containsKey("buyerAddress1")) {
            ispOrder.setBuyerAddress1(WinitStringUtils.removeSpecialChars(json.getString("buyerAddress1")));
        }
        if (json.containsKey("buyerAddress2")) {
            ispOrder.setBuyerAddress2(WinitStringUtils.removeSpecialChars(json.getString("buyerAddress2")));
        }
        if (json.containsKey("buyerHouseNo")) {
            ispOrder.setHouseNo(json.getString("buyerHouseNo"));
        }

        /*
         * if (json.containsKey("shipperAddrId")) {
         * ispOrder.setShipperAddrId(json.getInteger("shipperAddrId")); }
         */
        if (json.containsKey("shipperAddrCode")) {
            ispOrder.setShipperAddrCode(json.getString("shipperAddrCode"));
        }
        if (json.containsKey("ebaySellerId")) {
            ispOrder.setEbaySellerId(json.getString("ebaySellerId"));
        }
        if (json.containsKey("rmk")) {
            ispOrder.setRmk(StringUtils.trim(json.getString("rmk")));
        }

        //ISP下单新增电商平台字段
        if (json.containsKey("storeType")) {
            ispOrder.setStoreType(WinitStringUtils.removeSpecialChars(json.getString("storeType")));
        }
        
        /****************************** ispOrderLine **************************/
        List<ISPOrderLine> orderLineList = new ArrayList<ISPOrderLine>();
        List<ISPOrderMerchandise> merchandiseList = new ArrayList<ISPOrderMerchandise>();
        ISPOrderMerchandise ispOrderMerchandise = null;
        ISPOrderLine ispOrderLine = null;
        if (json.containsKey("packageList")) {
            JSONArray packageList = json.getJSONArray("packageList");
            for (Object obj : packageList) {
                JSONObject pack = (JSONObject) obj;
                ispOrderLine = new ISPOrderLine();
                if (pack.containsKey("weight")) {
                    ispOrderLine.setGrossWeight(pack.getBigDecimal("weight"));
                }
                if (pack.containsKey("length")) {
                    if(null==pack.get("length")||StringUtils.isBlank(pack.get("length").toString().trim())){
                        ispOrderLine.setLength(new BigDecimal(0));
                    }else{
                        positiveNumberImport2(pack, "length", "长");
                        ispOrderLine.setLength(pack.getBigDecimal("length"));
                    }
                }
                if (pack.containsKey("width")) {
                    if(null==pack.get("width")||StringUtils.isBlank(pack.get("width").toString().trim())){
                        ispOrderLine.setWidth(new BigDecimal(0));
                    }else{
                        positiveNumberImport2(pack, "width", "宽");
                        ispOrderLine.setWidth(pack.getBigDecimal("width"));
                    }
                }
                if (pack.containsKey("height")) {
                    if(null==pack.get("height")||StringUtils.isBlank(pack.get("height").toString().trim())){
                        ispOrderLine.setHeight(new BigDecimal(0));
                    }else{
                        positiveNumberImport2(pack, "height", "高");
                        ispOrderLine.setHeight(pack.getBigDecimal("height"));
                    }
                }
                if (json.containsKey("pickUpCode") && StringUtils.isNotBlank(json.getString("pickUpCode"))) {
                    ispOrderLine.setPickUpCode(json.getString("pickUpCode").trim());
                }
                if (pack.containsKey("merchandiseList")) {
                    JSONArray merlist = pack.getJSONArray("merchandiseList");
                    /****************************** ISPOrderMerchandise **************************/
                    if (merlist != null) {
                        for (Object o : merlist) {
                            JSONObject mer = (JSONObject) o;
                            ispOrderMerchandise = new ISPOrderMerchandise();
                            if (mer.containsKey("transactionID")) {
                                ispOrderMerchandise.setTransactionId(mer.getString("transactionID"));
                            }
                            if (mer.containsKey("itemID")) {
                                ispOrderMerchandise.setItemId(mer.getString("itemID"));
                            }
                            if (mer.containsKey("declaredValue")) {
                                ispOrderMerchandise.setDeclaredValue(mer.getBigDecimal("declaredValue"));
                            }
                            // 申报品名（中文）
                            if (mer.containsKey("declaredNameCn")) {
                                ispOrderMerchandise.setMerchandiseName(WinitStringUtils.removeSpecialChars(mer.getString("declaredNameCn").trim()));
                            }
                            // 申报品名（英文）
                            if (mer.containsKey("declaredNameEn")) {
                                ispOrderMerchandise.setMerchandiseNameEN(WinitStringUtils.removeSpecialChars(mer.getString("declaredNameEn").trim()));
                            }
                            // 商品数量未填写，则默认为1
                            if (mer.containsKey("merchandiseQuantity")) {
                                Long merchandiseQuantity = mer.getLong("merchandiseQuantity");
                                if(null != merchandiseQuantity && merchandiseQuantity > 0){
                                    ispOrderMerchandise.setMerchandiseQuantity(merchandiseQuantity);
                                }else{
                                    ispOrderMerchandise.setMerchandiseQuantity(1L);
                                }
                            }else{
                                ispOrderMerchandise.setMerchandiseQuantity(1L);
                            }
                            // 商品编码
                            if (mer.containsKey("merchandiseCode")) {
                                ispOrderMerchandise.setMerchandiseCode(WinitStringUtils.removeSpecialChars(mer.getString("merchandiseCode")));
                            } if (mer.containsKey("goodsLocation")) {
                                ispOrderMerchandise.setGoodsLocation(mer.getString("goodsLocation"));
                            }
                            
                            merchandiseList.add(ispOrderMerchandise);
                        }
                    }
                }
                ispOrderLine.setMerchandiseList(merchandiseList);
                orderLineList.add(ispOrderLine);
            }
        }
        CommandContext ctx = CommandContext.getContext();
        //如果ebay订单发货的单，则取source来源
        if(ApiConstant.API_SOURCE_GFS.equals(json.getString("source")))
        {
            ispOrder.setSource(json.getString("source"));
        }
        else
        {
            String source = (String) ctx.get(ApiConstant.API_SOURCE);
            // 设置其他信息，从上下文取得
            ispOrder.setSource(source);
        }
        ispOrder.setBpartnerId(Integer.parseInt(ctx.getUserId()));
        ispOrder.setBpartnerName(ctx.getUsername());
        ispOrder.setOrganizationId(ctx.getOrgId().intValue());

        ispOrder.setOrderLineList(orderLineList);
        return ispOrder;
    }

    /**
     * 费用预估参数校验
     */
    private void valiChargesParms(JSONObject json) {

        // winitProductCode
        ValidateUtil.validNotNull(json, "winitProductCode");
        // warehouseCode
        ValidateUtil.validNotNull(json, "warehouseCode");
        // startCountryCode
        ValidateUtil.validNotNull(json, "startCountryCode");
        // endCountryCode
        ValidateUtil.validNotNull(json, "endCountryCode");
        // startPostCode
        ValidateUtil.validNotNull(json, "startPostCode");
        // endPostCode
        ValidateUtil.validNotNull(json, "endPostCode");
        // dispatchType
        ValidateUtil.validNotNull(json, "dispatchType");

        /****************** package *******************/
        // packageList
        ValidateUtil.validNotNull(json, "listPackage");
        ValidateUtil.validList(json, "listPackage");

        JSONArray packageList = json.getJSONArray("listPackage");
        for (Object obj : packageList) {
            JSONObject pack = (JSONObject) obj;

            // weight
            ValidateUtil.validNotNull(pack, "weight");
            positiveNumber(pack, "weight");
            ValidateUtil.validBigDecimal(pack, "weight");
            //保留4位小数
            round(pack, 4, "weight");
            ValidateUtil.validatePrecision(pack, "weight",4,4);
            // length
            ValidateUtil.validNotNull(pack, "length");
            positiveNumber(pack, "length");
            ValidateUtil.validBigDecimal(pack, "length");
            ValidateUtil.validatePrecision(pack, "length", 4, 2);
            // width
            ValidateUtil.validNotNull(pack, "width");
            positiveNumber(pack, "width");
            ValidateUtil.validBigDecimal(pack, "width");
            ValidateUtil.validatePrecision(pack, "width", 4, 2);
            // height
            ValidateUtil.validNotNull(pack, "height");
            positiveNumber(pack, "height");
            ValidateUtil.validBigDecimal(pack, "height");
            ValidateUtil.validatePrecision(pack, "height", 4, 2);

        }

    }

    private void validCreateISPOrder(JSONObject json) {
        /*
         * // shipperAddrId ValidateUtil.validNotNull(json, "shipperAddrId");
         * ValidateUtil.validInteger(json, "shipperAddrId", true);
         * ValidateUtil.validMaxLength(json, "shipperAddrId", 10);
         */

        // shipperAddrCode
        ValidateUtil.validImportNotNull(json, "shipperAddrCode","寄件人地址Code");
        ValidateUtil.validImportMaxLength(json, "shipperAddrCode","寄件人地址Code", 8);
        validISPOrder(json);
    }

    private void validISPOrder(JSONObject json) {
        // refNo
        ValidateUtil.validImportMaxLength(json, "refNo","卖家订单号" ,50);

        // dispatchType
        ValidateUtil.validImportNotNull(json, "dispatchType","发货方式");
        validDispatchType(json);
        String dispatchType = json.getString("dispatchType");
        // warehouseCode
        if (dispatchType.equals(ApiConstant.DISPATCH_TYPE_SELLER) || dispatchType.equals(ApiConstant.DISPATCH_TYPE_SELF)) {
            ValidateUtil.validImportNotNull(json, "warehouseCode","仓库Code");
            ValidateUtil.validImportMaxLength(json, "warehouseCode","仓库Code", 30);
        } else {
            ValidateUtil.validImportMaxLength(json, "warehouseCode","仓库Code", 30);
        }
        // winitProductCode
        ValidateUtil.validImportNotNull(json, "winitProductCode","winit产品编码");
        ValidateUtil.validImportMaxLength(json, "winitProductCode","winit产品编码", 50);
        
        String winitProductCode = json.getString("winitProductCode");
        if(winitProductCode.equals(ApiConstant.TWPOST_CODE) && !dispatchType.equals(ApiConstant.DISPATCH_TYPE_SELF)){
            throw new ApiException(ErrorCode.DISPATH_TYPE_NOT_SUPPORT, winitProductCode,dispatchType);
        }

        /************** ebay ********************/
        // ebaySellerId
        ValidateUtil.validImportMaxLength(json, "ebaySellerId","ebay卖家ID", 50);
        /****************** buyer *******************/
        // buyerName
        ValidateUtil.validImportNotNull(json, "buyerName","收件人名字");
        ValidateUtil.validImportMaxLength(json, "buyerName","收件人名字", 80);
        // buyerEmail
        ValidateUtil.validImportMaxLength(json, "buyerEmail","收件人邮箱", 60);
        ValidateUtil.validEmailOtherReminder(json, "buyerEmail","收件人邮箱");
        // buyerZipCode
        ValidateUtil.validImportNotNull(json, "buyerZipCode","收件人邮编");
        ValidateUtil.validImportMaxLength(json, "buyerZipCode","收件人邮编", 10);
        // buyerCountry
        ValidateUtil.validImportNotNull(json, "buyerCountry","收件人国家");
        ValidateUtil.validImportMaxLength(json, "buyerCountry","收件人国家", 50);
        
        //是否可以不校验一些参数
        ISPOrderValidateCommand command = new ISPOrderValidateCommand();
        ISPOrder order = new ISPOrder();
        order.setWinitProductCode(json.getString("winitProductCode").trim());
        command.setOrder(order);
        command.setCtx(CommandContext.getContext());
        Map<String,Boolean> isNotValid=ispOrderService.isNotValidateSpecifiedParameters(command);
        if(!isNotValid.get(ApiConstant.IS_NOTVALIDATE_STATE)){
            // buyerState
            ValidateUtil.validImportNotNull(json, "buyerState","收件人州");
        }
        if(!isNotValid.get(ApiConstant.IS_NOTVALIDATE_PHONE)){
            // buyerContactNo
            ValidateUtil.validImportNotNull(json, "buyerContactNo","收件人电话");
        }
        if(!isNotValid.get(ApiConstant.IS_NOTVALIDATE_CITY)){
         // buyerCity
            ValidateUtil.validImportNotNull(json, "buyerCity","收件人城市");
        }
        
        ValidateUtil.validImportMaxLength(json, "buyerContactNo","收件人电话", 50);
        ValidateUtil.validImportMaxLength(json, "buyerState","收件人州", 50);
        ValidateUtil.validImportMaxLength(json, "buyerCity","收件人城市", 50);
        // buyerAddress1
        ValidateUtil.validImportNotNull(json, "buyerAddress1","收件人地址1");
        ValidateUtil.validImportMaxLength(json, "buyerAddress1","收件人地址1", 100);
        // buyerAddress2
        ValidateUtil.validImportMaxLength(json, "buyerAddress2","收件人地址2", 100);

        // buyerHouseNo
        ValidateUtil.validImportMaxLength(json, "buyerHouseNo","收件人门牌号", 10);
        
        ValidateUtil.validImportMaxLength(json, "rmk","备注" ,60);

        /****************** package *******************/
        // packageList
        ValidateUtil.validImportNotNull(json, "packageList","包裹");
        ValidateUtil.validListOtherReminder(json, "packageList","包裹");
        List<String> strList = new ArrayList<String>();
        JSONArray packageList = json.getJSONArray("packageList");
        for (Object obj : packageList) {
            JSONObject pack = (JSONObject) obj;
            // weight
            ValidateUtil.validImportNotNull(pack, "weight","重量");
            positiveNumberImport(pack, "weight","重量");
            ValidateUtil.validBigDecimalImport(pack, "weight","重量");
            //如果超过4位小数直接截取，保留4位
            round(pack, 4, "weight");
            ValidateUtil.validatePrecisionOtherReminder(pack, "weight","重量",4,4);
            
            if(!isNotValid.get(ApiConstant.IS_NOTVALIDATE_LENGTH)){
                // length
                ValidateUtil.validImportNotNull(pack, "length","长");
                positiveNumberImport(pack, "length","长");
            }
            if(!isNotValid.get(ApiConstant.IS_NOTVALIDATE_WIDTH)){
                // width
                ValidateUtil.validImportNotNull(pack, "width","宽");
                positiveNumberImport(pack, "width","宽");
            }
            if(!isNotValid.get(ApiConstant.IS_NOTVALIDATE_HEIGHT)){
                // height
                ValidateUtil.validImportNotNull(pack, "height","高");
                positiveNumberImport(pack, "height","高");
            }
            ValidateUtil.validBigDecimalImport(pack, "length","长");
            ValidateUtil.validatePrecisionOtherReminder(pack, "length","长", 4, 2);
            ValidateUtil.validBigDecimalImport(pack, "width","宽");
            ValidateUtil.validatePrecisionOtherReminder(pack, "width","宽", 4, 2);
            ValidateUtil.validBigDecimalImport(pack, "height","高");
            ValidateUtil.validatePrecisionOtherReminder(pack, "height","高", 4, 2);
            
            ValidateUtil.validImportMaxLength(json, "pickUpCode","拣货条码" ,50);
            validPickUpCode(json);

            /********* merchandiseList 商品列表 ***********/
            JSONArray merchandiseList = pack.getJSONArray("merchandiseList");
            if(null == merchandiseList || merchandiseList.size() < 1){
                throw new ApiException(ErrorCode.GOODS_NOT_NULL);
            }
            for (Object o : merchandiseList) {
                JSONObject merchandise = (JSONObject) o;
                // transactionID
//                ValidateUtil.validMustNumber(merchandise, "transactionID");
                ValidateUtil.validImportMaxLength(merchandise, "goodsLocation","库位" ,20);
                ValidateUtil.validImportMaxLength(merchandise, "transactionID","交易ID", 30);
                ValidateUtil.validImportMaxLength(merchandise, "merchandiseCode","商品编码", 50);
                
                // itemID
//                ValidateUtil.validMustNumber(merchandise, "itemID");
                ValidateUtil.validImportMaxLength(merchandise, "itemID","条目ID", 30);
                // declaredValue
                ValidateUtil.validImportNotNull(merchandise, "declaredValue","申报价格");
                positiveNumberImport(merchandise, "declaredValue","申报价格");
                ValidateUtil.validBigDecimalImport(merchandise, "declaredValue","申报价格");
                // ValidateUtil.validMaxLength(merchandise, "declaredValue",
                // 10);
                ValidateUtil.validatePrecisionOtherReminder(merchandise, "declaredValue","申报价格", 8, 2);
                // declaredName 中文和英文校验
                ValidateUtil.validImportNotNull(merchandise, "declaredNameCn","申报品名(中文)");
                ValidateUtil.validImportMaxLength(merchandise, "declaredNameCn","申报品名(中文)", 100);

                ValidateUtil.validImportNotNull(merchandise, "declaredNameEn","申报品名(英文)");
                ValidateUtil.validImportMaxLength(merchandise, "declaredNameEn","申报品名(英文)", 100);
                // 非中文校验
                /*if (!match("[^\u4e00-\u9fa5]+", merchandise.getString("declaredNameEn"))) {
                    // throw new ApiException(ErrorCode.FIELD_CN,
                    // merchandise.getString("declaredNameEn"));
                    throw new ApiException(ErrorCode.FIELD_CN, "申报品名(英文)");
                }*/
                //商品数量
                String merchandiseQuantity = merchandise.getString("merchandiseQuantity");
                if(StringUtils.isNotBlank(merchandiseQuantity)){
                    ValidateUtil.validMustNumber(merchandise, "merchandiseQuantity");
                    positiveNumberImport(merchandise, "merchandiseQuantity","商品数量");
                    ValidateUtil.validImportMaxLength(merchandise, "merchandiseQuantity","商品数量" , 10);
                }
                String transactionID = merchandise.getString("transactionID");
                String itemID = merchandise.getString("itemID");
                if (StringUtils.isNotBlank(transactionID) && StringUtils.isNotBlank(itemID)) {
                    strList.add(transactionID + "+" + itemID);
                }
            }
//            if (strList.size() > 0) {
//                removeDuplicateWithOrder(strList);
//            }
        }
    }

    /**
     * 校验发货方式是否符合规则
     */
    private void validDispatchType(JSONObject json) {
        String dispatchType = json.getString("dispatchType");
        if (!ApiConstant.DISPATCH_TYPE_SET.contains(dispatchType)) {
            throw new ApiException(ErrorCode.DISPATCHTYPE_VALUE_ERROR, dispatchType);
        }
    }
    
    private void validPickUpCode(JSONObject json){
        if(json.containsKey("pickUpCode")){
            String pickUpCode = json.getString("pickUpCode");
            String reg = "^[0-9a-zA-Z]{0,50}$";
            if(StringUtils.isNotBlank(pickUpCode) && !pickUpCode.matches(reg)){
                throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "pickUpCode");
            }
        }
    }

    private void validBatchImportISPOrder(JSONObject json) {
        // refNo
        ValidateUtil.validImportMaxLength(json, "refNo", "Seller Order No.", 50);
        // winitProductCode
        ValidateUtil.validImportNotNull(json, "winitProductCode", "Winit product");
        ValidateUtil.validImportMaxLength(json, "winitProductCode", "Winit product", 50);

        // dispatchType
        ValidateUtil.validImportNotNull(json, "dispatchType", "Shipping Method");
        validDispatchType(json);
        String dispatchType = json.getString("dispatchType");
        // warehouseName
        if (dispatchType.equals("S")) {
            ValidateUtil.validImportNotNull(json, "warehouseName", "Inspection Warehouse");
            ValidateUtil.validImportMaxLength(json, "warehouseName", "Inspection Warehouse", 50);
        } else {
            ValidateUtil.validImportMaxLength(json, "warehouseName", "Inspection Warehouse", 50);
        }
        /*
         * // shipperAddrId ValidateUtil.validImportNotNull(json,
         * "shipperAddrId","Address ID"); ValidateUtil.validInteger(json,
         * "shipperAddrId"); ValidateUtil.validImportMaxLength(json,
         * "shipperAddrId","Address ID", 10);
         */
        // shipperAddrCode
        ValidateUtil.validImportNotNull(json, "shipperAddrCode", "Address ID");
        ValidateUtil.validImportMaxLength(json, "shipperAddrCode", "Address ID", 8);

        /****************** buyer *******************/
        // buyerName
        ValidateUtil.validImportNotNull(json, "buyerName", "Buyer Fullname");
        ValidateUtil.validImportMaxLength(json, "buyerName", "Buyer Fullname", 80);
        // buyerEmail
        ValidateUtil.validImportMaxLength(json, "buyerEmail", "Buyer Email", 60);
        // buyerZipCode
        ValidateUtil.validImportNotNull(json, "buyerZipCode", "Buyer Postcode");
        ValidateUtil.validImportMaxLength(json, "buyerZipCode", "Buyer Postcode", 10);
        // buyerCountry
        ValidateUtil.validImportNotNull(json, "buyerCountry", "Buyer Country");
        ValidateUtil.validImportMaxLength(json, "buyerCountry", "Buyer Country", 50);
        
        
        //是否可以不校验一些参数
        ISPOrderValidateCommand command = new ISPOrderValidateCommand();
        ISPOrder order = new ISPOrder();
        order.setWinitProductCode(json.getString("winitProductCode").trim());
        command.setOrder(order);
        command.setCtx(CommandContext.getContext());
        Map<String,Boolean> isNotValid=ispOrderService.isNotValidateSpecifiedParameters(command);
        if(!isNotValid.get(ApiConstant.IS_NOTVALIDATE_STATE)){
            // buyerState
            ValidateUtil.validImportNotNull(json, "buyerState", "Buyer State");
        }
        if(!isNotValid.get(ApiConstant.IS_NOTVALIDATE_PHONE)){
            // buyerContactNo
            ValidateUtil.validImportNotNull(json, "buyerContactNo", "Buyer Contact Number");
        }
        if(!isNotValid.get(ApiConstant.IS_NOTVALIDATE_CITY)){
            // buyerCity
            ValidateUtil.validImportNotNull(json, "buyerCity", "Buyer City");
        }
        ValidateUtil.validImportMaxLength(json, "buyerState", "Buyer State", 50);
        ValidateUtil.validImportMaxLength(json, "buyerContactNo", "Buyer Contact Number", 50);
        ValidateUtil.validImportMaxLength(json, "buyerCity", "Buyer City", 50);
        
        // buyerAddress1
        ValidateUtil.validImportNotNull(json, "buyerAddress1", "Buyer Address1");
        ValidateUtil.validImportMaxLength(json, "buyerAddress1", "Buyer Address1", 100);
        // buyerAddress2
        ValidateUtil.validImportMaxLength(json, "buyerAddress2", "Buyer Address2", 100);
        // buyerHouseNo
        ValidateUtil.validImportMaxLength(json, "buyerHouseNo", "House No.", 10);

        /************** ebay ********************/
        // ebaySellerId
        ValidateUtil.validImportMaxLength(json, "ebaySellerId", "Ebay Seller ID", 50);
        ValidateUtil.validImportMaxLength(json, "rmk", "Remark", 60);
        /****************** package *******************/
        // packageList
        ValidateUtil.validNotNull(json, "packageList");
        ValidateUtil.validList(json, "packageList");
        List<String> sList = new ArrayList<String>();
        JSONArray packageList = json.getJSONArray("packageList");
        for (Object obj : packageList) {
            JSONObject pack = (JSONObject) obj;
            // weight
            ValidateUtil.validImportNotNull(pack, "weight", "Gross Weight (kg)");
            positiveNumberImport(pack, "weight", "Gross Weight (kg)");
            ValidateUtil.validBigDecimalImport(pack, "weight", "Gross Weight (kg)");
            ValidateUtil.validNumberMax(pack, new BigDecimal(10000), "weight");
            //如果超过4位小数直接截取，保留4位
            round(pack, 4, "weight");
            ValidateUtil.validatePrecisionImport(pack, "weight", "Gross Weight (kg)",4,4);
            if(!isNotValid.get(ApiConstant.IS_NOTVALIDATE_LENGTH)){
                // length
                ValidateUtil.validImportNotNull(pack, "length", "Length (cm)");
                positiveNumberImport(pack, "length", "Length (cm)");
            }
            if(!isNotValid.get(ApiConstant.IS_NOTVALIDATE_WIDTH)){
                // width
                ValidateUtil.validImportNotNull(pack, "width", "Width (cm)");
                positiveNumberImport(pack, "width", "Width (cm)");
            }
            if(!isNotValid.get(ApiConstant.IS_NOTVALIDATE_HEIGHT)){
                // height
                ValidateUtil.validImportNotNull(pack, "height", "Height (cm)");
                positiveNumberImport(pack, "height", "Height (cm)");
            }
            ValidateUtil.validBigDecimalImport(pack, "length", "Length (cm)");
            ValidateUtil.validNumberMax(pack, new BigDecimal(10000), "length");
            ValidateUtil.validatePrecisionImport(pack, "length", "Length (cm)", 4, 2);
      
            ValidateUtil.validBigDecimalImport(pack, "width", "Width (cm)");
            ValidateUtil.validNumberMax(pack, new BigDecimal(10000), "width");
            ValidateUtil.validatePrecisionImport(pack, "width", "Width (cm)", 4, 2);
         
            ValidateUtil.validBigDecimalImport(pack, "height", "Height (cm)");
            ValidateUtil.validNumberMax(pack, new BigDecimal(10000), "height");
            ValidateUtil.validatePrecisionImport(pack, "height", "Height (cm)", 4, 2);
            /********* merchandiseList 商品列表 ***********/
            JSONArray merchandiseList = pack.getJSONArray("merchandiseList");
            if(null == merchandiseList || merchandiseList.size() < 1){
                throw new ApiException(ErrorCode.GOODS_NOT_NULL);
            }
            for (Object o : merchandiseList) {
                JSONObject merchandise = (JSONObject) o;
                ValidateUtil.validImportMaxLength(merchandise, "goodsLocation", "Storage Location", 20);
//                ValidateUtil.validMustNumber(merchandise, "transactionID");
                ValidateUtil.validImportMaxLength(merchandise, "transactionID","交易ID", 30);
                ValidateUtil.validImportMaxLength(merchandise, "merchandiseCode","SKU No.", 50);
                // itemID
//                ValidateUtil.validMustNumber(merchandise, "itemID");
                ValidateUtil.validImportMaxLength(merchandise, "itemID","条目ID", 30);
                // declaredValue
                ValidateUtil.validImportNotNull(merchandise, "declaredValue", "Declared Value (USD)");
                positiveNumberImport(merchandise, "declaredValue", "Declared Value (USD)");
                ValidateUtil.validBigDecimalImport(merchandise, "declaredValue", "Declared Value (USD)");
                // ValidateUtil.validImportMaxLength(merchandise,
                // "declaredValue", "Declared Value (USD)", 10);
                ValidateUtil.validatePrecisionImport(merchandise, "declaredValue", "Declared Value (USD)", 8, 2);
                // declaredName 中文和英文校验
                ValidateUtil.validImportNotNull(merchandise, "declaredNameCn", "Declared Name (Chn)");
                ValidateUtil.validImportMaxLength(merchandise, "declaredNameCn", "Declared Name (Chn)", 100);

                ValidateUtil.validImportNotNull(merchandise, "declaredNameEn", "Declared Name (Eng)");
                ValidateUtil.validImportMaxLength(merchandise, "declaredNameEn", "Declared Name (Eng)", 100);
//                // 非中文校验
//                if (!match("[^\u4e00-\u9fa5]+", merchandise.getString("declaredNameEn"))) {
//                    throw new ApiException(ErrorCode.FIELD_CN, merchandise.getString("declaredNameEn"));
//                }
                //商品数量
                String merchandiseQuantity = merchandise.getString("merchandiseQuantity");
                if(StringUtils.isNotBlank(merchandiseQuantity)){
                    if(!merchandiseQuantity.matches("^[0-9]*$")){
                        throw new ApiException(ErrorCode.MUST_NUMBER, "商品数量");
                    }
                    positiveNumberImport(merchandise, "merchandiseQuantity","商品数量");
                    ValidateUtil.validImportMaxLength(merchandise, "merchandiseQuantity","商品数量" , 10);
                }
                String transactionID = merchandise.getString("transactionID");
                String itemID = merchandise.getString("itemID");
                if (StringUtils.isNotBlank(transactionID) && StringUtils.isNotBlank(itemID)) {
                    sList.add(transactionID + "+" + itemID);
                }
            }
//            if (sList.size() > 0) {
//                removeDuplicateWithOrder(sList);
//            }
        }
    }

    private void round(JSONObject json, int scale, String field) {
        if(json.containsKey(field)){
            Object weight = json.get(field);
            if(weight != null && StringUtils.isNotBlank(weight.toString())){
                String s = weight.toString();
                BigDecimal bd = new BigDecimal(s);
                bd = bd.setScale(4, RoundingMode.HALF_UP);
                
                json.put(field, bd.toString());
            }
        }
    }

    private void validUpdateISPOrder(JSONObject json) {
        // 必填字段不允许修改为空
        boolean required = true;

        // orderNo
        ValidateUtil.validNotNull(json, "orderNo");
        ValidateUtil.validMaxLength(json, "orderNo", 60);
        // refNo
        ValidateUtil.validMaxLength(json, "refNo", 50);
        // winitProductCode
        ValidateUtil.validMaxLength(json, "winitProductCode", 50, required);

        /****************** buyer *******************/
        // buyerName
        ValidateUtil.validMaxLength(json, "buyerName", 80, required);
        // buyerEmail
        ValidateUtil.validMaxLength(json, "buyerEmail", 60);
        ValidateUtil.validEmail(json, "buyerEmail");
        // buyerZipCode
        ValidateUtil.validMaxLength(json, "buyerZipCode", 10, required);
        // buyerCountry
        ValidateUtil.validMaxLength(json, "buyerCountry", 50, required);
        ValidateUtil.validMaxLength(json, "rmk", 60);
        
        
        //是否可以不校验一些参数
        ISPOrderValidateCommand command = new ISPOrderValidateCommand();
        ISPOrder order = new ISPOrder();
        order.setWinitProductCode(json.getString("winitProductCode").trim());
        command.setOrder(order);
        command.setCtx(CommandContext.getContext());
        Map<String,Boolean> isNotValid=ispOrderService.isNotValidateSpecifiedParameters(command);
        if(!isNotValid.get(ApiConstant.IS_NOTVALIDATE_STATE)){
            // buyerState
            ValidateUtil.validMaxLength(json, "buyerState", 50, required);
        }
        if(!isNotValid.get(ApiConstant.IS_NOTVALIDATE_PHONE)){
            // buyerContactNo
            ValidateUtil.validMaxLength(json, "buyerContactNo", 50, required);
        }
        if(!isNotValid.get(ApiConstant.IS_NOTVALIDATE_CITY)){
         // buyerCity
            ValidateUtil.validMaxLength(json, "buyerCity", 50, required);
        }
        // buyerAddress1
        ValidateUtil.validMaxLength(json, "buyerAddress1", 100, required);
        // buyerAddress2
        ValidateUtil.validMaxLength(json, "buyerAddress2", 100);
        // buyerHouseNo
        ValidateUtil.validMaxLength(json, "buyerHouseNo", 10);

        /****************** shipper *******************/
        /*
         * // shipperAddrId ValidateUtil.validNotNull(json, "shipperAddrId");
         * ValidateUtil.validInteger(json, "shipperAddrId");
         * ValidateUtil.validMaxLength(json, "shipperAddrId", 10);
         */
        // shipperAddrCode
        ValidateUtil.validNotNull(json, "shipperAddrCode");
        ValidateUtil.validMaxLength(json, "shipperAddrCode", 8);
        // dispatchType
        ValidateUtil.validNotNull(json, "dispatchType");
        validDispatchType(json);
        String dispatchType = json.getString("dispatchType");
        // warehouseName
        if (dispatchType.equals("S")) {
            ValidateUtil.validImportNotNull(json, "warehouseName", "Inspection Warehouse");
            ValidateUtil.validImportMaxLength(json, "warehouseName", "Inspection Warehouse", 50);
        } else {
            ValidateUtil.validImportMaxLength(json, "warehouseName", "Inspection Warehouse", 50);
        }

        /************** ebay ********************/
        // ebaySellerId
        ValidateUtil.validMaxLength(json, "ebaySellerId", 50);
        /****************** package *******************/
        // packageList
        ValidateUtil.validList(json, "packageList", required);
        List<String> strList = new ArrayList<String>();
        if (json.containsKey("packageList")) {
            JSONArray packageList = json.getJSONArray("packageList");
            for (Object obj : packageList) {
                JSONObject pack = (JSONObject) obj;
                // weight
                positiveNumber(pack, "weight");
                ValidateUtil.validBigDecimal(pack, "weight", required);
                ValidateUtil.validNumberMax(pack, new BigDecimal(10000), "weight");
                //如果超过4位小数直接截取，保留4位
                round(pack, 4, "weight");
                ValidateUtil.validatePrecision(pack, "weight",4,4);
                
                if(!isNotValid.get(ApiConstant.IS_NOTVALIDATE_LENGTH)){
                    // length
                    positiveNumber(pack, "length");
                    ValidateUtil.validBigDecimal(pack, "length", required);
                    ValidateUtil.validNumberMax(pack, new BigDecimal(10000), "length");
                    ValidateUtil.validatePrecision(pack, "length", 4, 2);
                }
                if(!isNotValid.get(ApiConstant.IS_NOTVALIDATE_WIDTH)){
                 // width
                    positiveNumber(pack, "width");
                    ValidateUtil.validBigDecimal(pack, "width", required);
                    ValidateUtil.validNumberMax(pack, new BigDecimal(10000), "width");
                    ValidateUtil.validatePrecision(pack, "width", 4, 2);
                }
                if(!isNotValid.get(ApiConstant.IS_NOTVALIDATE_HEIGHT)){
                    // height
                    positiveNumber(pack, "height");
                    ValidateUtil.validBigDecimal(pack, "height", required);
                    ValidateUtil.validNumberMax(pack, new BigDecimal(10000), "height");
                    ValidateUtil.validatePrecision(pack, "height", 4, 2);
                }
                
                /********* merchandiseList 商品列表 ***********/
                JSONArray merchandiseList = pack.getJSONArray("merchandiseList");
                for (Object o : merchandiseList) {
                    JSONObject merchandise = (JSONObject) o;
                    ValidateUtil.validMaxLength(merchandise, "goodsLocation", 20);
                    ValidateUtil.validMaxLength(merchandise, "merchandiseCode", 50);
                    // transactionID
//                    ValidateUtil.validMustNumber(merchandise, "transactionID");
                    ValidateUtil.validMaxLength(merchandise, "transactionID", 30);
                    // itemID
//                    ValidateUtil.validMustNumber(merchandise, "itemID");
                    ValidateUtil.validMaxLength(merchandise, "itemID", 30);
                    // declaredValue
                    ValidateUtil.validNotNull(merchandise, "declaredValue");
                    positiveNumber(merchandise, "declaredValue");
                    ValidateUtil.validBigDecimal(merchandise, "declaredValue");
                    // ValidateUtil.validMaxLength(merchandise, "declaredValue",
                    // 10);
                    ValidateUtil.validatePrecision(merchandise, "declaredValue", 8, 2);
                    // declaredName 中文和英文校验
                    ValidateUtil.validNotNull(merchandise, "declaredNameCn");
                    ValidateUtil.validMaxLength(merchandise, "declaredNameCn", 100);

                    ValidateUtil.validNotNull(merchandise, "declaredNameEn");
                    ValidateUtil.validMaxLength(merchandise, "declaredNameEn", 100);
                    // 非中文校验
                    /*if (!match("[^\u4e00-\u9fa5]+", merchandise.getString("declaredNameEn"))) {
                        throw new ApiException(ErrorCode.FIELD_CN, merchandise.getString("declaredNameEn"));
                    }*/
                    //商品数量
                    String merchandiseQuantity = merchandise.getString("merchandiseQuantity");
                    if(StringUtils.isNotBlank(merchandiseQuantity)){
                        ValidateUtil.validMustNumber(merchandise, "merchandiseQuantity");
                        positiveNumberImport(merchandise, "merchandiseQuantity","商品数量");
                        ValidateUtil.validImportMaxLength(merchandise, "merchandiseQuantity","商品数量" , 10);
                    }
                    String transactionID = merchandise.getString("transactionID");
                    String itemID = merchandise.getString("itemID");
                    if (StringUtils.isNotBlank(transactionID) && StringUtils.isNotBlank(itemID)) {
                        strList.add(transactionID + "+" + itemID);
                    }
                }
//                if (strList.size() > 0) {
//                    removeDuplicateWithOrder(strList);
//                }
            }
        }

    }

    private void validSearchISPOrder(JSONObject json) {
        // orderNo
        ValidateUtil.validMaxLength(json, "orderNo", 60);
        // refNo
        ValidateUtil.validMaxLength(json, "refNo", 50);
        // refNo
        ValidateUtil.validMaxLength(json, "buyerCountry", 20);
        // buyerName
        ValidateUtil.validMaxLength(json, "buyerName", 80);
        // winitProductCode
        ValidateUtil.validMaxLength(json, "winitProductCode", 50);
        // status
        ValidateUtil.validMaxLength(json, "status", 60);
        // orderDateStart
        ValidateUtil.validDateString(json, "orderDateStart", DateUtil.SIMPLE_DATE_STRING);
        // orderDateEnd
        ValidateUtil.validDateString(json, "orderDateEnd", DateUtil.SIMPLE_DATE_STRING);
        ValidateUtil.validDateBefore(json, "orderDateStart", "orderDateEnd");

        // pageParams
        if (json.containsKey("pageParams")) {
            Object obj = json.get("pageParams");
            if (obj instanceof JSONObject) {
                JSONObject pageParams = (JSONObject) obj;
                // pageNo
                ValidateUtil.validInteger(pageParams, "pageNo");

                // pageSize
                ValidateUtil.validInteger(pageParams, "pageSize");

                if (isExistValue(pageParams, "pageNo")) {
                    int pageNo = pageParams.getInteger("pageNo");
                    if (pageNo < 1) {
                        throw new ApiException(ErrorCode.FIELD_ERROR, "pageNo");
                    }
                }
                if (isExistValue(pageParams, "pageSize")) {
                    int pageSize = pageParams.getInteger("pageSize");
                    if (pageSize < 1) {
                        throw new ApiException(ErrorCode.FIELD_ERROR, "pageSize");
                    }
                }
            } else {
                throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "pageParams");
            }
        }
    }

    private ExportISPOrderCommand buildSearchOrderCommand(JSONObject json) {
        ExportISPOrderCommand command = new ExportISPOrderCommand();
        // orderNo
        if (json.containsKey("orderNo")) {
            command.setOrderNo(json.getString("orderNo"));
        }
        // trackingNo
        if (json.containsKey("trackingNo")) {
            command.setExpressNo(json.getString("trackingNo"));;
        }
        // refNo
        if (json.containsKey("refNo")) {
            command.setSellerOrderNo(json.getString("refNo"));
        }
        // buyerName
        if (json.containsKey("buyerName")) {
            command.setBuyerFullname(json.getString("buyerName"));
        }
        // winitProductCode
        if (json.containsKey("winitProductCode")) {
            command.setWinitProductName(json.getString("winitProductCode"));
        }
        // productCatalogLv2
        if (json.containsKey("productCatalogLv2")) {
            command.setProductCatalogLv2(json.getString("productCatalogLv2"));
        }
        if (json.containsKey("buyerCountry")) {
        	command.setBuyerCountry(json.getString("buyerCountry"));
        }
        
        if (isExistValue(json, "orderType")) {
            if ("3".equals(json.getString("orderType"))) command.setType(EnumOrderType.UNBOUND);
            if ("2".equals(json.getString("orderType"))) command.setType(EnumOrderType.ALL);
            if ("1".equals(json.getString("orderType"))) command.setType(EnumOrderType.NORM);
            if ("0".equals(json.getString("orderType"))) command.setType(EnumOrderType.EX);
        }
        // status
        if (json.containsKey("status")) {
            if (StringUtils.isNotBlank(json.getString("status"))) {
                String[] arr = json.getString("status").split(",");
                command.setStatus(Arrays.asList(arr));
            }
        }

        // orderDateStart
        if (json.containsKey("orderDateStart")) {
            String orderDateStart = json.getString("orderDateStart");
            orderDateStart += " 00:00:00";
            Date from = DateUtil.parse2Date(orderDateStart, DateUtil.FULL_DATE_STRING);
            command.setDateFrom(from);
        }
        // orderDateEnd
        if (json.containsKey("orderDateEnd")) {
            String orderDateEnd = json.getString("orderDateEnd");
            orderDateEnd += " 23:59:59";
            Date to = DateUtil.parse2Date(orderDateEnd, DateUtil.FULL_DATE_STRING);
            command.setDateTo(to);
        }

        return command;
    }

    private Searchable buildSearchPageParams(JSONObject json) {
        int pageNo = ApiConstant.PAGE_NO_DEFAULT;
        int pageSize = ApiConstant.PAGE_SIZE_DEFAULT;
        // pageParams
        if (isExistValue(json, "pageParams")) {
            JSONObject pageParams = json.getJSONObject("pageParams");

            if (ValidateUtil.isIntNumber(pageParams.getString("pageNo"))) {
                pageNo = pageParams.getInteger("pageNo");
                if (pageNo <= 0) {
                    throw new ApiException(ErrorCode.FIELD_ERROR, "pageNo");
                }
            } else if (isExistValue(pageParams, "pageNo") && !ValidateUtil.isIntNumber(pageParams.getString("pageNo"))) {
                throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "pageNo");
            }

            if (ValidateUtil.isIntNumber(pageParams.getString("pageSize"))) {
                pageSize = pageParams.getInteger("pageSize");
                if (pageSize <= 0) {
                    throw new ApiException(ErrorCode.FIELD_ERROR, "pageSize");
                }
            } else if (isExistValue(pageParams, "pageSize")
                       && !ValidateUtil.isIntNumber(pageParams.getString("pageSize"))) {
                throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "pageSize");
            }

        }
        Searchable search = Searchable.newSearchable();
        search.setPage(pageNo, pageSize);
        
        //增加排序
        if (json.containsKey("sort") && json.containsKey("sortColumn")) {
            String sort = json.getString("sort");
            String sortColumn = json.getString("sortColumn");
            if(StringUtils.equalsIgnoreCase(sort, "asc")){
                search.addSort(new Sort(Direction.ASC, sortColumn));
            } else {
                search.addSort(new Sort(Direction.DESC, sortColumn));
            }
            search.addSort(new Sort(Direction.DESC, "ORDER_ID"));
        } else {
            //给默认排序字段
            search.addSort(new Sort(Direction.DESC, "ORDER_ID"));
        }
        

        return search;
    }

    private Searchable buildExportPageParams(JSONObject json) {
        int pageNo = ApiConstant.PAGE_NO_DEFAULT;
        int pageSize = ApiConstant.EXPORT_MAX_COUNT;
        // pageParams
        if (json != null && json.containsKey("pageParams")) {
            JSONObject pageParams = json.getJSONObject("pageParams");
            // pageNo
            if (pageParams.containsKey("pageNo")) {
                pageNo = pageParams.getInteger("pageNo");
            }
            // pageSize
            if (pageParams.containsKey("pageSize")) {
                pageSize = pageParams.getInteger("pageSize");
                if (pageSize > ApiConstant.EXPORT_MAX_COUNT) {
                    pageSize = ApiConstant.EXPORT_MAX_COUNT;
                }
            }
        }
        Searchable search = Searchable.newSearchable();
        search.setPage(pageNo, pageSize);

        search.addSort(new Sort(Direction.DESC, "ORDER_ID"));

        return search;
    }

    private List<Map<String, Object>> buildReturnISPOrderList(List<ISPOrder> datalist, String orderType) {
        List<Map<String, Object>> rslist = new ArrayList<Map<String, Object>>();
        Map<String, Object> map = null;
        for (ISPOrder order : datalist) {
            map = buildReturnISPOrder(order, orderType);
            rslist.add(map);
        }
        return rslist;
    }

    private List<Map<String, Object>> buildReturnISPOrderOutList(List<ISPOrder> datalist, String orderType) {
        List<Map<String, Object>> rslist = new ArrayList<Map<String, Object>>();
        Map<String, Object> map = null;
        for (ISPOrder order : datalist) {
            map = buildReturnOutISPOrder(order, orderType);
            rslist.add(map);
        }
        return rslist;
    }

    /**
     * 组装查询订单详情返回参数
     * 
     * @param order
     * @param orderType
     * @return
     */
    private Map<String, Object> buildReturnISPOrderInfo(ISPOrder order, String orderType) {
        Map<String, Object> map = new HashMap<String, Object>();
        /************************** order ***********************/
        map.put("orderNo", order.getOrderNo());
        map.put("refNo", order.getSellerOrderNo());
        map.put("winitProductCode", order.getWinitProductCode());
        map.put("winitProductName", order.getWinitProductName());
        map.put("isValid", EnumISPOrderStatus.PD.getStatus().equals(order.getStatus()) ? "N" : "Y");
        if (orderType.equals(ApiConstant.ISP_ORDER_TPYE_EX)) {
            map.put("errMsg", order.getErrMsg());
        }
        String orderDate = DateUtil.parse2String(order.getOrderDate(), DateUtil.FULL_DATE_STRING);
        map.put("orderDate", orderDate);
        map.put("status", order.getStatus());
        map.put("dispatchType", order.getDispatchType());
        //电商平台
        map.put("storeType", order.getStoreType());
        /************************* buyer ************************/
        map.put("buyerName", order.getBuyerFullname());
        map.put("buyerContactNo", order.getBuyerContactNumber());
        map.put("buyerEmail", order.getBuyerEmail());
        map.put("buyerZipCode", order.getBuyerPostcode());
        map.put("buyerCountry", order.getBuyerCountry());
        map.put("occurTime", order.getUpdated());
        map.put("buyerState", order.getBuyerState());
        map.put("buyerCity", order.getBuyerCity());
        map.put("buyerAddress1", order.getBuyerAddress1());
        map.put("buyerAddress2", order.getBuyerAddress2());
        map.put("buyerHouseNo", order.getHouseNo());
        map.put("rmk", order.getRmk());

        /*********************** shipper ************************/
        // map.put("shipperAddrId", order.getShipperAddrId());

        map.put("shipperAddrCode", order.getShipperAddrCode());

        map.put("shipperCountry", order.getShipperCountry());
        map.put("shipperCountryCode", order.getShipperCountryCode());
        map.put("shipperState", order.getShipperState());
        map.put("shipperCity", order.getShipperCity());
        map.put("shipperDistrict", order.getShipperDistrict());
        map.put("shipperPostCode", order.getShipperPostcode());
        map.put("shipperAddress1", order.getShipperAddress1());
        map.put("shipperAddress2", order.getShipperAddress2());
        map.put("shipperEmail", order.getShipperEmail());
        /************** ebay ********************/
        // ebaySellerId
        map.put("ebaySellerId", order.getEbaySellerId());
        /************* 仓库 *************/
        map.put("warehouseName", order.getWarehouseName());
        map.put("warehouseCode", order.getWarehouseCode());
        if (orderType.equals(ApiConstant.ISP_ORDER_TPYE_EX)) {
            List<Map<String, Object>> ispexceptionList = new ArrayList<Map<String, Object>>();
            Map<String, Object> ispexceptionMap = null;
            List<ISPOrderException> ispexceptions = order.getExceptionList();
            if (null != ispexceptions) {
                for (ISPOrderException ispexception : ispexceptions) {
                    ispexceptionMap = new HashMap<String, Object>();
                    ispexceptionMap.put("errorCode", ispexception.getErrorCode());
                    ispexceptionMap.put("description", ispexception.getDescription());
                    ispexceptionList.add(ispexceptionMap);
                }
            } else {
                ispexceptionMap = new HashMap<String, Object>();
                ispexceptionMap.put("errorCode", "");
                ispexceptionMap.put("description", "");
                ispexceptionList.add(ispexceptionMap);
            }

            map.put("ispexceptionList", ispexceptionList);
        }
        List<Map<String, Object>> olList = new ArrayList<Map<String, Object>>();
        List<Map<String, Object>> mlList = new ArrayList<Map<String, Object>>();
        Map<String, Object> orderLineMap = null;
        Map<String, Object> merchandiseMap = null;
        List<ISPOrderLine> orderLineList = order.getOrderLineList();
        if (orderLineList != null) {
            for (ISPOrderLine orderLine : orderLineList) {
                /*********************** package ************************/
                orderLineMap = new HashMap<String, Object>();
                orderLineMap.put("weight", orderLine.getGrossWeight());
                orderLineMap.put("length", orderLine.getLength());
                orderLineMap.put("width", orderLine.getWidth());
                orderLineMap.put("height", orderLine.getHeight());
                orderLineMap.put("weightActual", orderLine.getCfmGrossWeight());
                orderLineMap.put("lengthActual", orderLine.getCfmLength());
                orderLineMap.put("widthActual", orderLine.getCfmWidth());
                orderLineMap.put("heightActual", orderLine.getCfmHeight());
                orderLineMap.put("declaredTotalValue", orderLine.getDeclaredValue());

                List<ISPOrderMerchandise> merchandiseList = orderLine.getMerchandiseList();
                if (merchandiseList != null && merchandiseList.size() > 0) {
                    for (ISPOrderMerchandise m : merchandiseList) {
                        merchandiseMap = new HashMap<String, Object>();
                        if(StringUtils.isBlank(m.getMerchandiseCode())){
                            merchandiseMap.put("merchandiseCode", "");
                        }else{
                            merchandiseMap.put("merchandiseCode", m.getMerchandiseCode());
                        }
                        if(StringUtils.isBlank(m.getTransactionId())){
                            merchandiseMap.put("transactionID", "");
                        }else{
                            merchandiseMap.put("transactionID", m.getTransactionId());
                        }
                        if(StringUtils.isBlank(m.getItemId())){
                            merchandiseMap.put("itemID", "");
                        }else{
                            merchandiseMap.put("itemID", m.getItemId());
                        }
                        merchandiseMap.put("declaredValue", m.getDeclaredValue());
                        merchandiseMap.put("declaredNameCn", m.getMerchandiseName());
                        merchandiseMap.put("declaredNameEn", m.getMerchandiseNameEN());
                        merchandiseMap.put("ebayItemPrice", m.getEbayItemPrice());
                        if(null != m.getMerchandiseQuantity() && m.getMerchandiseQuantity() > 0){
                            merchandiseMap.put("merchandiseQuantity", m.getMerchandiseQuantity());
                        }else{
                            merchandiseMap.put("merchandiseQuantity", 1L);
                        }
                        if(StringUtils.isBlank(m.getGoodsLocation())){
                            merchandiseMap.put("goodsLocation", "");
                        }else{
                            merchandiseMap.put("goodsLocation", m.getGoodsLocation());
                        }
                        mlList.add(merchandiseMap);
                    }
                }
                orderLineMap.put("merchandiseList", mlList);
                olList.add(orderLineMap);
            }
            if (orderLineList.size() > 0) {
                String expressNo = orderLineList.get(0).getExpressno();
                if (StringUtils.isNotBlank(expressNo)) {
                    map.put("expressNo", expressNo);
                    map.put("trackingNo", expressNo);
                } else {
                    map.put("expressNo", "");
                    map.put("trackingNo", "");
                }
            }
        }
        map.put("packageList", olList);
        //增加source来源
        map.put("source", order.getSource());
        return map;

    }

    private Map<String, Object> buildReturnISPOrder(ISPOrder order, String orderType) {
        Map<String, Object> map = new HashMap<String, Object>();
        List<ISPOrderLine> orderLineList = order.getOrderLineList();
        /************************** order ***********************/
        map.put("order_id", order.getOrderId());
        map.put("exceptPortWarehouseOutBoundDate", "");
        if(order.getInboundDate() != null ){
        	try {
        		Integer SLA = order.getPortWarehouseOutBoundSLA() + order.getDelaySLA();
        		map.put("exceptPortWarehouseOutBoundDate", DateUtils.addHours(order.getInboundDate(), SLA));
			} catch (Exception e) {
				logger.error(order.getOrderNo()+"的预计出库时间转换失败~~~~~~~~~");
			}
        }
        map.put("claimStatus", order.getClaimStatus());
        map.put("orderNo", order.getOrderNo());
        map.put("refNo", order.getSellerOrderNo());
        map.put("buyerCountry", order.getBuyerCountry());
        map.put("occurTime", order.getUpdated());
        map.put("winitProductCode", order.getWinitProductCode());
        map.put("winitProductName", order.getWinitProductName());
        map.put("isValid", EnumISPOrderStatus.PD.getStatus().equals(order.getStatus()) ? "N" : "Y");
        if (orderType.equals(ApiConstant.ISP_ORDER_TPYE_EX)) {
            map.put("errMsg", order.getErrMsg());
        }
        String orderDate = DateUtil.parse2String(order.getOrderDate(), DateUtil.FULL_DATE_STRING);
        map.put("orderDate", orderDate);
        map.put("status", order.getStatus());
        map.put("storeType", order.getStoreType());
        /************************* buyer ************************/
        map.put("buyerName", order.getBuyerFullname());

        if (orderType.equals(ApiConstant.ISP_ORDER_TPYE_EX)) {
            List<Map<String, Object>> ispexceptionList = new ArrayList<Map<String, Object>>();
            Map<String, Object> ispexceptionMap = null;
            List<ISPOrderException> ispexceptions = order.getExceptionList();
            if (null != ispexceptions) {
                for (ISPOrderException ispexception : ispexceptions) {
                    ispexceptionMap = new HashMap<String, Object>();
                    ispexceptionMap.put("errorCode", ispexception.getErrorCode());
                    ispexceptionMap.put("description", ispexception.getDescription());
                    ispexceptionList.add(ispexceptionMap);
                }
            } else {
                ispexceptionMap = new HashMap<String, Object>();
                ispexceptionMap.put("errorCode", "");
                ispexceptionMap.put("description", "");
                ispexceptionList.add(ispexceptionMap);
            }
            map.put("ispexceptionList", ispexceptionList);
        }
        List<Map<String, Object>> olList = new ArrayList<Map<String, Object>>();
        Map<String, Object> orderLineMap = null;
        int quantity = 0;

        if (orderLineList != null) {
            for (int i = 0; i < orderLineList.size(); i++) {
                /*********************** package ************************/
                orderLineMap = new HashMap<String, Object>();
                ISPOrderLine orderLine = orderLineList.get(i);
                
                //卖家网站订单查询列表增加一列‘商品数量’
                List<ISPOrderMerchandise> merchandiseList =  orderLine.getMerchandiseList();
                for(ISPOrderMerchandise merchandise : merchandiseList){
                    if(null == merchandise.getMerchandiseQuantity()){
                        merchandise.setMerchandiseQuantity(1L);
                    }
                    quantity += merchandise.getMerchandiseQuantity();
                }
                orderLineMap.put("quantity", quantity);
                
                orderLineMap.put("weight", orderLine.getGrossWeight());
                //增加一列“核实重量”
                orderLineMap.put("cfmGrossWeight", orderLine.getCfmGrossWeight().compareTo(new BigDecimal(0)) == 0 ? "" : orderLine.getCfmGrossWeight());
                orderLineMap.put("length", orderLine.getLength());
                orderLineMap.put("width", orderLine.getWidth());
                orderLineMap.put("height", orderLine.getHeight());
                olList.add(orderLineMap);
            }
            if (orderLineList.size() > 0) {
                String labelNo = orderLineList.get(0).getLabelno();
                String expressNo = orderLineList.get(0).getExpressno();
                if (StringUtils.isNotBlank(labelNo)) {
                    map.put("labelNo", labelNo);
                } else {
                    map.put("labelNo", "");
                }
                if (StringUtils.isNotBlank(expressNo)) {
                    map.put("expressNo", expressNo);
                    map.put("trackingNo", expressNo);
                } else {
                    map.put("expressNo", "");
                    map.put("trackingNo", "");
                }
            }
        }
        map.put("packageList", olList);
        return map;
    }

    private Map<String, Object> buildReturnOutISPOrder(ISPOrder order, String orderType) {
        Map<String, Object> map = new HashMap<String, Object>();
        /************************** order ***********************/
        map.put("orderNo", order.getOrderNo());
        map.put("refNo", order.getSellerOrderNo());
        map.put("buyerCountry", order.getBuyerCountry());
        map.put("occurTime", order.getUpdated());
        map.put("winitProductCode", order.getWinitProductCode());
        map.put("winitProductName", order.getWinitProductName());
        map.put("isValid", EnumISPOrderStatus.PD.getStatus().equals(order.getStatus()) ? "N" : "Y");
        if (orderType.equals(ApiConstant.ISP_ORDER_TPYE_EX)) {
            map.put("errMsg", order.getErrMsg());
        }
        String orderDate = DateUtil.parse2String(order.getOrderDate(), DateUtil.FULL_DATE_STRING);
        map.put("orderDate", orderDate);
        map.put("status", order.getStatus());

        // ebaySellerId
        map.put("ebaySellerId", order.getEbaySellerId());
        /************************* buyer ************************/
        map.put("buyerName", order.getBuyerFullname());
        map.put("buyerContactNo", order.getBuyerContactNumber());
        map.put("buyerEmail", order.getBuyerEmail());
        map.put("buyerZipCode", order.getBuyerPostcode());
        map.put("buyerCountry", order.getBuyerCountry());
        map.put("occurTime", order.getUpdated());
        map.put("buyerState", order.getBuyerState());
        map.put("buyerCity", order.getBuyerCity());
        map.put("buyerAddress1", order.getBuyerAddress1());
        map.put("buyerAddress2", order.getBuyerAddress2());
        map.put("buyerHouseNo", order.getHouseNo());
        map.put("rmk", order.getRmk());
        /*********************** shipper ************************/
        // map.put("shipperAddrId", order.getShipperAddrId());

        map.put("shipperAddrCode", order.getShipperAddrCode());

        map.put("dispatchType", order.getDispatchType());
        List<ISPOrderLine> orderLineList = order.getOrderLineList();
        if (orderLineList.size() > 0) {
            ISPOrderLine iSPOrderLine = orderLineList.get(0);
            if (StringUtils.isNotBlank(iSPOrderLine.getExpressno())) {
                map.put("trackingNo", iSPOrderLine.getExpressno());
            } else {
                map.put("trackingNo", iSPOrderLine.getLabelno());
            }
        } else {
            map.put("trackingNo", "");
        }
        /************* 仓库 *************/
        map.put("warehouseID", order.getWarehouseID());
        map.put("warehouseName", order.getWarehouseName());

        if (orderType.equals(ApiConstant.ISP_ORDER_TPYE_EX)) {
            List<Map<String, Object>> ispexceptionList = new ArrayList<Map<String, Object>>();
            Map<String, Object> ispexceptionMap = null;
            List<ISPOrderException> ispexceptions = order.getExceptionList();
            if (null != ispexceptions) {
                for (ISPOrderException ispexception : ispexceptions) {
                    ispexceptionMap = new HashMap<String, Object>();
                    ispexceptionMap.put("errorCode", ispexception.getErrorCode());
                    ispexceptionMap.put("description", ispexception.getDescription());
                    ispexceptionList.add(ispexceptionMap);
                }
            } else {
                ispexceptionMap = new HashMap<String, Object>();
                ispexceptionMap.put("errorCode", "");
                ispexceptionMap.put("description", "");
                ispexceptionList.add(ispexceptionMap);
            }

            map.put("ispexceptionList", ispexceptionList);
        }
        List<Map<String, Object>> olList = new ArrayList<Map<String, Object>>();
        List<Map<String, Object>> mlList = new ArrayList<Map<String, Object>>();
        Map<String, Object> orderLineMap = null;
        Map<String, Object> merchandiseMap = null;

        for (int i = 0; i < orderLineList.size(); i++) {
            /*********************** package ************************/
            orderLineMap = new HashMap<String, Object>();
            //增加一列“核实重量”
            ISPOrderLine ispOrderLine = orderLineList.get(i);
            orderLineMap.put("cfmGrossWeight", ispOrderLine.getCfmGrossWeight().compareTo(new BigDecimal(0)) == 0 ? "" : ispOrderLine.getCfmGrossWeight());
            orderLineMap.put("weight", ispOrderLine.getGrossWeight());
            orderLineMap.put("length", ispOrderLine.getLength());
            orderLineMap.put("width", ispOrderLine.getWidth());
            orderLineMap.put("height", ispOrderLine.getHeight());
            orderLineMap.put("volume", ispOrderLine.getVolume());
            orderLineMap.put("packageDesc", ispOrderLine.getDescription());
            List<ISPOrderMerchandise> merchandiseList = ispOrderLine.getMerchandiseList();
            for (int j = 0; j < merchandiseList.size(); j++) {
                merchandiseMap = new HashMap<String, Object>();
                merchandiseMap.put("transactionID", merchandiseList.get(j).getTransactionId());
                merchandiseMap.put("itemID", merchandiseList.get(j).getItemId());
                merchandiseMap.put("declaredValue", merchandiseList.get(j).getDeclaredValue());
                merchandiseMap.put("declaredNameCn", merchandiseList.get(j).getMerchandiseName());
                merchandiseMap.put("declaredNameEn", merchandiseList.get(j).getMerchandiseNameEN());
                merchandiseMap.put("merchandiseQuantity", merchandiseList.get(j).getMerchandiseQuantity());
                merchandiseMap.put("goodsLocation", merchandiseList.get(j).getGoodsLocation());
                merchandiseMap.put("merchandiseCode", merchandiseList.get(j).getMerchandiseCode());
                mlList.add(merchandiseMap);
            }
            orderLineMap.put("merchandiseList", mlList);
            olList.add(orderLineMap);
        }
        map.put("packageList", olList);
        return map;
    }

    private void validOrderNo(JSONObject json) {
        // orderNo
        ValidateUtil.validNotNull(json, "orderNo");
        ValidateUtil.validMaxLength(json, "orderNo", 60);
    }

    // 判断非必填字段是否有值
    public boolean isExistValue(JSONObject jsonObject, String key) {
        if (jsonObject.containsKey(key)) {
            return !"".equals(jsonObject.getString(key).trim());
        }
        return false;
    }

    // 效验用户是不是isp用户
    public void checkIspRight() {
        ContractCommand command = new ContractCommand();
        command.setBusiType("ISP");
        command.setBpartnerId(Long.parseLong(CommandContext.getContext().getUserId()));
        boolean rightStatus = agreementService.isOpenContract(command);

        if (!rightStatus) {
            throw new ApiException(ErrorCode.USERNAME_ISNOT_ISP_USER);
        }
    }

    // 效验重量价格大于0
    public void positiveNumber(JSONObject json, String key) {
        if (isExistValue(json, key) && ValidateUtil.isBigDecimal(json.getString(key))) {
            BigDecimal bd = new BigDecimal(json.getString(key));
            if (bd.compareTo(new BigDecimal("0")) <= 0) {
                throw new ApiException(ErrorCode.FIELD_INPUT_ERROR, key);
            }
        }
    }

    // 效验大于0,批量导入提示
    public void positiveNumberImport(JSONObject json, String key, String xmlKye) {
        if (isExistValue(json, key) && ValidateUtil.isBigDecimal(json.getString(key))) {
            BigDecimal bd = new BigDecimal(json.getString(key));
            if (bd.compareTo(new BigDecimal("0")) <= 0) {
                throw new ApiException(ErrorCode.FIELD_INPUT_ERROR, xmlKye);
            }
        }

    }
   
    // 效验大于0,批量导入提示
    public void positiveNumberImport2(JSONObject json, String key, String xmlKye) {
        if (isExistValue(json, key) && ValidateUtil.isBigDecimal(json.getString(key))) {
            BigDecimal bd = new BigDecimal(json.getString(key));
            if (bd.compareTo(new BigDecimal("0")) < 0) {
                throw new ApiException(ErrorCode.FIELD_INPUT_ERROR, xmlKye);
            }
        }

    }
    

    /**
     * 批量提交ISP未提交订单列表中的校验异常订单
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/batchCommitCheckExOrder")
    public String batchCommitCheckExOrder(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        CommitCheckExOrderCommand command = null;
        Object obj = requestMsg.getData();
        Map<String, Object> data = new HashMap<String, Object>();
        if (obj instanceof JSONObject) {
            JSONObject json = (JSONObject) obj;
            // 组装command
            command = buildCommitCheckExOrderCommand(json);
        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }
        BatchResult result = ispOrderService.batchCommitCheckExOrder(command);

        if (result != null) {
            data.put("successCount", result.getSuccess());
            data.put("failedCount", result.getFailed());
            data.put("errorMsg", result.getErrMsg());
            responseMsg.setData(data);
        }
        return SUCCESS;
    }

    /**
     * 新增订单-收件人信息校验
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/recipientAddressCheck")
    public String recipientAddressCheck(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        ISPOrderValidateCommand command = null;
        // 1.根据验货仓校验启始地址
        Object obj = requestMsg.getData();
        if (obj instanceof JSONObject) {
            JSONObject json = (JSONObject) obj;
            // 校验收件人地址信息是否必填、长度、类型
            validateRecipient(json);
            // 组装command
            command = buildOrderValidateCommand(json);
        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }

        // 校验收件人信息
        iSPOrderStepValidateService.validateBCountryPostcodeAddr(command);
        responseMsg.setMsg("SUCCESS");

        return SUCCESS;
    }

    /**
     * 新增订单-打包规则校验
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/packageRulesCheck")
    public String packageRulesCheck(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        ISPOrderValidateCommand command = new ISPOrderValidateCommand();
        Object obj = requestMsg.getData();
        if (obj instanceof JSONObject) {
            ISPOrder order = new ISPOrder();
            List<ISPOrderLine> orderLineList = new ArrayList<ISPOrderLine>();
            ISPOrderLine orderLine = null;
            JSONObject json = (JSONObject) obj;
            // 校验包裹信息是否必填、长度、类型
            validatePackage(json);
            // 组装command
            if (json.containsKey("winitProductCode")) {
                order.setWinitProductCode(json.getString("winitProductCode").trim());
            }
            JSONArray packageList = json.getJSONArray("packageList");
            for (Object o : packageList) {
                JSONObject pack = (JSONObject) o;
                orderLine = new ISPOrderLine();
                if (pack.containsKey("length")) {
                    orderLine.setLength(pack.getBigDecimal("length"));
                }
                if (pack.containsKey("width")) {
                    orderLine.setWidth(pack.getBigDecimal("width"));
                }
                if (pack.containsKey("height")) {
                    orderLine.setHeight(pack.getBigDecimal("height"));
                }
                if (pack.containsKey("weight")) {
                    orderLine.setGrossWeight(pack.getBigDecimal("weight"));
                }
                orderLineList.add(orderLine);
            }
            order.setOrderLineList(orderLineList);
            command.setOrder(order);
        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }
        // 校验包裹信息
        iSPOrderStepValidateService.validatePackage(command);
        responseMsg.setMsg("SUCCESS");
        return SUCCESS;
    }

    /**
     * 新增订单-第三方订单是否重复校验
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/thirdOrderCheck")
    public String thirdOrderCheck(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        ISPOrderValidateCommand command = null;
        Object obj = requestMsg.getData();
        if (obj instanceof JSONObject) {
            JSONObject json = (JSONObject) obj;
            // 校验收件人地址信息是否必填、长度、类型
            validateMerchandise(json);
            // 组织command
            command = buildOrderMerchandiseCommand(json);
        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }
        // 校验第三方订单是否重复校验
        // 校验商品信息
        iSPOrderStepValidateService.validateProductInformation(command);
        responseMsg.setMsg("SUCCESS");
        return SUCCESS;
    }

    
    /**
     * ISP订单接收重量接口
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/receiveWeight")
    public String receiveWeight(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        Object obj = requestMsg.getData();
        if (obj instanceof JSONObject) {
            JSONObject json = (JSONObject) obj;
            // 校验参数
            validISPOrderWeight(json);

            // 解析报文
            List<YanWenOrder> yanWenOrders = buildISPOrderWeight(json);
            YanWenOrderLibraryCommand command = new YanWenOrderLibraryCommand();
            command.setYanWenOrder(yanWenOrders);
            command.setCtx(CommandContext.getContext());
            yanWenOrderService.updateOrderWeight(command);
        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }
        return SUCCESS;
    }
    
    /**
     * 第三方系统对接万邑通轨迹接口：接收第三方系统轨迹参数，生成订单轨迹，并返回处理结果
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/addTracking")
    public String addTracking(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        Object obj = requestMsg.getData();
        if (obj instanceof JSONObject) {
            JSONObject json = (JSONObject) obj;
            // 校验参数
            validISPOrderTracking(json);
            // 解析报文
            OrderTrackingVo orderTrackingVo = buildISPOrderTracking(json);
            ispOrderTrackingService.createISPOrderTracking(orderTrackingVo);
        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }
        return SUCCESS;
    }
    
    /**
     * 验证接收重量接口参数
     * 
     * @param json
     */
    private void validISPOrderWeight(JSONObject json) {
        if (json.containsKey("orderList")) {
            JSONArray orderList = json.getJSONArray("orderList");
            for (Object obj : orderList) {
                JSONObject order = (JSONObject) obj;
                ValidateUtil.valid(order, "expressNo", 60, true);
                ValidateUtil.valid(order, "weight", 16, true);
                ValidateUtil.validNotNull(order, "occurtime");
                ValidateUtil.validDateString(order, "occurtime", ValidateUtil.DATE_PATTERN_BASE);
            }
        } else {
            logger.info("接受燕文重量接口的订单信息为空");
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "orderList");
        }
    }

    
    /**
     * 构建接收重量接口数据
     * 
     * @param json
     * @return
     */
    private List<YanWenOrder> buildISPOrderWeight(JSONObject json) {
        List<YanWenOrder> listOrders = new ArrayList<YanWenOrder>();
        YanWenOrder yanWenOrder = null;
        if (json.containsKey("orderList")) {
            JSONArray packageList = json.getJSONArray("orderList");
            for (Object obj : packageList) {
                JSONObject pack = (JSONObject) obj;
                yanWenOrder = new YanWenOrder();
                if (pack.containsKey("expressNo")) {
                    yanWenOrder.setExpressNo(pack.getString("expressNo").trim());
                }
                if (pack.containsKey("occurtime")) {
                    yanWenOrder.setOccurTime(pack.getDate("occurtime"));
                }
                if (pack.containsKey("weight")) {
                    yanWenOrder.setWeigth(pack.getBigDecimal("weight"));
                }
                if (pack.containsKey("height")) {
                    yanWenOrder.setHeight(pack.getBigDecimal("weigth"));
                }
                if (pack.containsKey("width")) {
                    yanWenOrder.setWidth(pack.getBigDecimal("width"));
                }
                if (pack.containsKey("length")) {
                    yanWenOrder.setLength(pack.getBigDecimal("length"));
                }
                listOrders.add(yanWenOrder);
            }
        }
        return listOrders;
    }
    
    /**
     * 封装批量提交校验异常订单命令
     * 
     * @param json
     * @return
     */
    private CommitCheckExOrderCommand buildCommitCheckExOrderCommand(JSONObject json) {
        CommitCheckExOrderCommand command = new CommitCheckExOrderCommand();
        if (json.containsKey("orderNoList")) {
            JSONArray arrays = json.getJSONArray("orderNoList");
            List<String> orderNolist = new ArrayList<String>();
            if (arrays != null && !arrays.isEmpty()) {
                for (Object obj : arrays) {
                    JSONObject str = (JSONObject) obj;
                    orderNolist.add(str.getString("orderNo"));
                }
            }
            command.setOrderNolist(orderNolist);
        }
        return command;
    }

    /**
     * 封装校验订单对象
     * 
     * @param json
     * @return
     */
    private ISPOrderValidateCommand buildOrderValidateCommand(JSONObject json) {
        ISPOrderValidateCommand command = new ISPOrderValidateCommand();
        ISPOrder order = new ISPOrder();
        if (json.containsKey("winitProductCode")) {
            order.setWinitProductCode(json.getString("winitProductCode"));
        }
        if (json.containsKey("warehouseCode")) {
            order.setWarehouseCode(json.getString("warehouseCode"));
        }
        if (json.containsKey("buyerFullname")) {
            order.setBuyerFullname(json.getString("buyerFullname"));
        }
        if (json.containsKey("buyerEmail")) {
            order.setBuyerEmail(json.getString("buyerEmail"));
        }
        if (json.containsKey("buyerPostcode")) {
            order.setBuyerPostcode(json.getString("buyerPostcode"));
        }
        if (json.containsKey("buyerCountry")) {
            order.setBuyerCountry(json.getString("buyerCountry"));
        }
        if (json.containsKey("buyerContactNumber")) {
            order.setBuyerContactNumber(json.getString("buyerContactNumber"));
        }
        if (json.containsKey("buyerState")) {
            order.setBuyerState(json.getString("buyerState"));
        }
        if (json.containsKey("buyerCity")) {
            order.setBuyerCity(json.getString("buyerCity"));
        }
        if (json.containsKey("buyerAddress1")) {
            order.setBuyerAddress1(json.getString("buyerAddress1"));
        }
        if (json.containsKey("buyerAddress2")) {
            order.setBuyerAddress2(json.getString("buyerAddress2"));
        }
        command.setOrder(order);
        return command;
    }
    
    /**
     * 封装商品信息对象
     * 
     * @param json
     * @return
     */
    private ISPOrderValidateCommand buildOrderMerchandiseCommand(JSONObject json) {
        ISPOrderValidateCommand command = new ISPOrderValidateCommand();
        ISPOrder order = new ISPOrder();
        if (json.containsKey("orderNo")) {
            order.setOrderNo(json.getString("orderNo").trim());
        }
        //收件人信息
        if (json.containsKey("buyerCountry")) {
            String buyCountry=json.getString("buyerCountry").trim();
            order.setBuyerCountry(buyCountry);
        }
        if (json.containsKey("buyerState")) {
            order.setBuyerState(json.getString("buyerState"));
        }
        if (json.containsKey("buyerCity")) {
            order.setBuyerCity(json.getString("buyerCity"));
        }
        if (json.containsKey("buyerAddress1")) {
            order.setBuyerAddress1(json.getString("buyerAddress1"));
        }
        if (json.containsKey("buyerAddress2")) {
            order.setBuyerAddress2(json.getString("buyerAddress2"));
        }
        
        List<ISPOrderLine> orderLineList = new ArrayList<ISPOrderLine>();
        ISPOrderLine orderLine = new ISPOrderLine();
        List<ISPOrderMerchandise> merchList = new ArrayList<ISPOrderMerchandise>();
        JSONArray merchandiseList = json.getJSONArray("merchandiseList");
        for (Object obj : merchandiseList) {
            JSONObject merch = (JSONObject) obj;
            ISPOrderMerchandise merchandise = new ISPOrderMerchandise();
            if (merch.containsKey("merchandiseNameCN")) {
                merchandise.setMerchandiseName(merch.getString("merchandiseNameCN"));
            }
            if (merch.containsKey("merchandiseNameEN")) {
                merchandise.setMerchandiseNameEN(merch.getString("merchandiseNameEN"));
            }
            if (merch.containsKey("declaredValue")) {
                merchandise.setDeclaredValue(merch.getBigDecimal("declaredValue"));
            }
            if (merch.containsKey("transactionId")) {
                merchandise.setTransactionId(merch.getString("transactionId"));
            }
            if (merch.containsKey("itemId")) {
                merchandise.setItemId(merch.getString("itemId"));
            }
            // 商品数量未填写，则默认为1
            if (merch.containsKey("merchandiseQuantity")) {
                Long merchandiseQuantity = merch.getLong("merchandiseQuantity");
                if(null != merchandiseQuantity && merchandiseQuantity > 0){
                    merchandise.setMerchandiseQuantity(merchandiseQuantity);
                }else{
                    merchandise.setMerchandiseQuantity(1L);
                }
            }
            merchList.add(merchandise);
        }
        orderLine.setMerchandiseList(merchList);
        orderLineList.add(orderLine);
        order.setOrderLineList(orderLineList);
        command.setOrder(order);
        return command;
    }

    /**
     * 校验包裹信息是否必填、长度、类型
     * 
     * @param json
     */
    private void validatePackage(JSONObject json) {

        ValidateUtil.validNotNull(json, "winitProductCode");

        ValidateUtil.validNotNull(json, "packageList");
        ValidateUtil.validList(json, "packageList");

        JSONArray packageList = json.getJSONArray("packageList");
        for (Object obj : packageList) {
            JSONObject pack = (JSONObject) obj;
            // weight
            ValidateUtil.validNotNull(pack, "weight");
            positiveNumber(pack, "weight");
            ValidateUtil.validBigDecimal(pack, "weight");
            ValidateUtil.validNumberMax(pack, new BigDecimal(10000), "weight");
            //保留4位小数
            round(pack, 4, "weight");
            ValidateUtil.validatePrecision(pack, "weight",4,4);
 
            // length
            ValidateUtil.validNotNull(pack, "length");
            positiveNumber(pack, "length");
            ValidateUtil.validBigDecimal(pack, "length");
            ValidateUtil.validNumberMax(pack, new BigDecimal(10000), "length");
            ValidateUtil.validatePrecision(pack, "length", 4, 2);
            // width
            ValidateUtil.validNotNull(pack, "width");
            positiveNumber(pack, "width");
            ValidateUtil.validBigDecimal(pack, "width");
            ValidateUtil.validNumberMax(pack, new BigDecimal(10000), "width");
            ValidateUtil.validatePrecision(pack, "width", 4, 2);
            // height
            ValidateUtil.validNotNull(pack, "height");
            positiveNumber(pack, "height");
            ValidateUtil.validBigDecimal(pack, "height");
            ValidateUtil.validNumberMax(pack, new BigDecimal(10000), "height");
            ValidateUtil.validatePrecision(pack, "height", 4, 2);
        }
    }

    /**
     * 校验收件人地址信息是否必填、长度、类型
     * 
     * @param json
     */
    private void validateRecipient(JSONObject json) {
        // 必填字段不允许修改为空
        boolean required = true;
        // winitProductCode
        ValidateUtil.validNotNull(json, "winitProductCode");
        ValidateUtil.validMaxLength(json, "winitProductCode", 60, required);
        // warehouseCode
        ValidateUtil.validNotNull(json, "warehouseCode");
        ValidateUtil.validMaxLength(json, "warehouseCode", 20, required);
        // buyerName
        ValidateUtil.validNotNull(json, "buyerFullname");
        ValidateUtil.validMaxLength(json, "buyerFullname", 80, required);
        // buyerEmail
        ValidateUtil.validMaxLength(json, "buyerEmail", 30, required);
        ValidateUtil.validEmail(json, "buyerEmail");
        // buyerZipCode
        ValidateUtil.validNotNull(json, "buyerPostcode");
        ValidateUtil.validMaxLength(json, "buyerPostcode", 10, required);
        // buyerCountry
        ValidateUtil.validNotNull(json, "buyerCountry");
        ValidateUtil.validMaxLength(json, "buyerCountry", 50, required);
        
        //是否可以不校验一些参数
        ISPOrderValidateCommand command = new ISPOrderValidateCommand();
        ISPOrder order = new ISPOrder();
        order.setWinitProductCode(json.getString("winitProductCode").trim());
        command.setOrder(order);
        command.setCtx(CommandContext.getContext());
        Map<String,Boolean> isNotValid=ispOrderService.isNotValidateSpecifiedParameters(command);
        if(!isNotValid.get(ApiConstant.IS_NOTVALIDATE_STATE)){
            // buyerState
            ValidateUtil.validNotNull(json, "buyerState");
            ValidateUtil.validMaxLength(json, "buyerState", 50, required);
        }
        if(!isNotValid.get(ApiConstant.IS_NOTVALIDATE_PHONE)){
            // buyerContactNo
            ValidateUtil.validNotNull(json, "buyerContactNumber");
            ValidateUtil.validMaxLength(json, "buyerContactNumber", 50, required);
        }
        if(!isNotValid.get(ApiConstant.IS_NOTVALIDATE_CITY)){
            // buyerCity
            ValidateUtil.validNotNull(json, "buyerCity");
            ValidateUtil.validMaxLength(json, "buyerCity", 50, required);
        }
        // buyerAddress1
        ValidateUtil.validNotNull(json, "buyerAddress1");
        ValidateUtil.validMaxLength(json, "buyerAddress1", 100, required);
        // buyerAddress2
        ValidateUtil.validMaxLength(json, "buyerAddress2", 100);
    }

    /**
     * 校验商品信息是否必填、长度、类型
     * 
     * @param json
     */
    private void validateMerchandise(JSONObject json) {
        // 必填字段不允许修改为空
        boolean required = true;
        //收件人信息
        // buyerCountry
        ValidateUtil.validNotNull(json, "buyerCountry");
        ValidateUtil.validMaxLength(json, "buyerCountry", 50, required);
        //buyerState
        ValidateUtil.validNotNull(json, "buyerState");
        ValidateUtil.validMaxLength(json, "buyerState", 50, required);
        //buyerCity
        ValidateUtil.validNotNull(json, "buyerCity");
        ValidateUtil.validMaxLength(json, "buyerCity", 50, required);
        //buyerAddress1
        ValidateUtil.validNotNull(json, "buyerAddress1");
        ValidateUtil.validMaxLength(json, "buyerAddress1", 100, required);
        //buyerAddress2
        ValidateUtil.validMaxLength(json, "buyerAddress2", 100);
        
        ValidateUtil.validNotNull(json, "merchandiseList");
        ValidateUtil.validList(json, "merchandiseList");
        JSONArray merchandiseList = json.getJSONArray("merchandiseList");
        List<String> strList = new ArrayList<String>();
        for (Object obj : merchandiseList) {
            JSONObject merch = (JSONObject) obj;
            // transactionID
//            ValidateUtil.validMustNumber(merch, "transactionId");
            ValidateUtil.validMaxLength(merch, "transactionId", 30);
            // itemID
//            ValidateUtil.validMustNumber(merch, "itemId");
            ValidateUtil.validMaxLength(merch, "itemId", 30);
            // declaredValue
            ValidateUtil.validNotNull(merch, "declaredValue");
            positiveNumber(merch, "declaredValue");
            ValidateUtil.validBigDecimal(merch, "declaredValue", required);
            // ValidateUtil.validMaxLength(merch, "declaredValue", 10,
            // required);
            ValidateUtil.validatePrecisionImport(merch, "declaredValue", "Declared Value (USD)", 8, 2);
            // declaredName
            ValidateUtil.validNotNull(merch, "merchandiseNameCN");
            ValidateUtil.validMaxLength(merch, "merchandiseNameCN", 100, required);
            // declaredNameEN
            ValidateUtil.validNotNull(merch, "merchandiseNameEN");
            ValidateUtil.validMaxLength(merch, "merchandiseNameEN", 100, required);
            // 非中文校验  bug 14743 去掉限制
            /*if (!match("[^\u4e00-\u9fa5]+", merch.getString("merchandiseNameEN"))) {
                throw new ApiException(ErrorCode.FIELD_CN, merch.getString("merchandiseNameEN"));
            }*/
            //商品数量
            String merchandiseQuantity = merch.getString("merchandiseQuantity");
            if(StringUtils.isNotBlank(merchandiseQuantity)){
                ValidateUtil.validMustNumber(merch, "merchandiseQuantity");
                positiveNumberImport(merch, "merchandiseQuantity","商品数量");
                ValidateUtil.validImportMaxLength(merch, "merchandiseQuantity","商品数量" , 10);
            }
            String transactionId = merch.getString("transactionId");
            String itemId = merch.getString("itemId");
            if (StringUtils.isNotBlank(transactionId)) {
                if (StringUtils.isBlank(itemId)) {
                    ValidateUtil.validNotNull(merch, "itemId");
                }
            } else {
                if (StringUtils.isNotBlank(itemId)) {
                    ValidateUtil.validNotNull(merch, "transactionId");
                }
            }

            if (StringUtils.isNotBlank(transactionId) && StringUtils.isNotBlank(itemId)) {
                strList.add(transactionId.trim() + "+" + itemId.trim());
            }
        }
//        if (strList.size() > 0) {
//            removeDuplicateWithOrder(strList);
//        }
    }
    
    
    /**
     * 校验第三方系统推送的轨迹数据是否规范、合理
     * @param json
     */
    private void validISPOrderTracking(JSONObject json) {
         // 必填字段不允许修改为空
        boolean required = true;
        //轨迹Code
        ValidateUtil.validNotNull(json, "trackingCode");
        ValidateUtil.validMaxLength(json, "trackingCode", 32, required);
        //轨迹时间
        ValidateUtil.validNotNull(json, "trackingDate");
        ValidateUtil.validDateString(json, "trackingDate", ValidateUtil.DATE_PATTERN_BASE);
        //操作地点
        ValidateUtil.validNotNull(json, "trackingAddr");
        ValidateUtil.validMaxLength(json, "trackingAddr", 50, required);
        //重量
        BigDecimal weight = json.getBigDecimal("weight");
        if (null != weight) {
            positiveNumber(json, "weight");
            ValidateUtil.validBigDecimal(json, "weight");
            ValidateUtil.validNumberMax(json, new BigDecimal(10000), "weight");
            //保留4位小数
            round(json, 4, "weight");
            ValidateUtil.validatePrecision(json, "weight", 4, 4);
        }
        //跟踪号
        ValidateUtil.validNotNull(json, "expressNo");
        ValidateUtil.validMaxLength(json, "expressNo", 60, required);
        //ISP订单号
        String orderNo = json.getString("orderNo");
        if(StringUtils.isNotBlank(orderNo)){
            ValidateUtil.validNotNull(json, "orderNo");
            ValidateUtil.validMaxLength(json, "orderNo", 60, required);
        }
    }
    
    /**
     * 封装订单轨迹对象列表
     * @param json
     * @return
     */
    private OrderTrackingVo buildISPOrderTracking(JSONObject json) {
        OrderTrackingVo trackingVo = new OrderTrackingVo();
        if (json.containsKey("trackingCode")) {
            trackingVo.setTrackingCode(json.getString("trackingCode"));
        }
        if (json.containsKey("trackingDate")) {
            trackingVo.setTrackingDate(json.getDate("trackingDate"));
        }
        if (json.containsKey("trackingAddr")) {
            trackingVo.setTrackingAddr(json.getString("trackingAddr"));
        }
        if (json.containsKey("weight")) {
            trackingVo.setWeight(json.getBigDecimal("weight"));
        }
        if (json.containsKey("expressNo")) {
            trackingVo.setExpressNo(json.getString("expressNo"));
        }
        if (json.containsKey("orderNo")) {
            trackingVo.setOrderNo(json.getString("orderNo"));
        }
        return trackingVo;
    }

    /**
     * @param regex 正则表达式字符串
     * @param str 要匹配的字符串
     * @return 如果str 符合 regex的正则表达式格式,返回true, 否则返回 false;
     */
    private static boolean match(String regex, String str) {
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(str);
        return matcher.matches();
    }
    
    private Map<String, Object> buildEditOrder(GfsOrder gfs){
        Map<String, Object> data = new HashMap<String, Object>();
        data.put("gfsOrderId", gfs.getOrderId());
        data.put("status", gfs.getStatus());
        data.put("warehouseID", gfs.getWinitwarehouseID());
        data.put("winitOrderCode", gfs.getWinitOrderCode());
        data.put("warehouseCode", gfs.getWarehouseCode());
        data.put("warehouseName", gfs.getWarehouseName());
        data.put("deliveryWay", gfs.getDeliveryWayCode());
        data.put("deliveryWayName", gfs.getDeliveryWayName());
        data.put("insuranceType", gfs.getInsuranceType());
        data.put("buyerUserId", gfs.getBuyerUserId());
        data.put("sellerUserId", gfs.getSellerUserId());
        data.put("buyerFullname", gfs.getBuyerFullname());
        data.put("buyerEmail", gfs.getBuyerEmail());
        data.put("buyerPhone", gfs.getBuyerPhone());
        data.put("buyerCountry", gfs.getBuyerCountry());
        data.put("buyerState", gfs.getBuyerState());
        data.put("buyerCity", gfs.getBuyerCity());
        data.put("buyerPostCode", gfs.getBuyerPostCode());
        data.put("buyerAddreess", gfs.getBuyerAddreess2());
        data.put("buyerAddreess2", gfs.getBuyerAddreess3());
        data.put("checkOutDate", gfs.getCheckOutDate());
        data.put("paymentDate", gfs.getPaymentDate());
        data.put("postageDate", gfs.getPostageDate());
        data.put("feedbackSent", gfs.getFeedbackSent());
        data.put("feedbackReceive", gfs.getFeedbackReceive());
        data.put("paymentReceivedDate", gfs.getPaymentReceivedDate());
        data.put("paymentMethod", gfs.getPaymentMethod());
        data.put("postedDate", gfs.getPostedDate());
        data.put("postageService", gfs.getPostageService());
        data.put("lastEmailSent", gfs.getDeliveryDate());//发货时间
        data.put("saleDate", gfs.getSaleDate());
        data.put("errorMsg", gfs.getErrorMsg());
        data.put("ebayProductList", gfs.getEbayProductList());
        data.put("productList", gfs.getProductList());
        data.put("ebayTransactionType", gfs.getEbayTransactionType());
        data.put("orderType", gfs.getOrderType());
        data.put("shipperAddrCode", gfs.getShipperAddrCode());
        data.put("winitProductCode", gfs.getWinitProductCode());
        data.put("winitProductName", gfs.getWinitProductName());
        data.put("extent", gfs.getExtent());
        data.put("weight", gfs.getWeight());
        data.put("width", gfs.getWidth());
        data.put("height", gfs.getHeight());
        data.put("doorplateNumbers", gfs.getDoorpLateNumbers());        
        data.put("trackingNo", gfs.getTrackingNo());
        data.put("totalAllPrice", gfs.getTotalAllPrice());
        data.put("totalPriceCurrency", gfs.getTotalPriceCurrency());
        
        //需求 10452 新增平台订单详情：
        data.put("sellerOrderCode", gfs.getSellerOrderCode());//卖家订单号
        data.put("sellerUserId", gfs.getSellerUserId());//卖家ID
        data.put("buyerUserId", gfs.getBuyerUserId());//买家ID
        data.put("platform", gfs.getPlatform());//订单来源
        data.put("sellerOrderCode", gfs.getSellerOrderCode());//客户订单号
        data.put("paymentReceivedDate", gfs.getPaymentReceivedDate());//付款时间
        data.put("txMemo", gfs.getTxMemo());//备注
        data.put("txGiftMessage", gfs.getTxGiftMessage());//包装信息
        data.put("postageService", gfs.getPostageService());//原始派送方式
        data.put("txShipping", gfs.getTxShipping());//运费
        data.put("txTax", gfs.getTxTax());//税费
        data.put("txHandling", gfs.getTxHandling());//处理费
        data.put("txDiscount", gfs.getTxDiscount());//优惠
        data.put("txInsuranceType", gfs.getTxInsuranceType());//保险类型
        data.put("txCurrency", gfs.getTxCurrency());//币种
        data.put("txStoreKey", gfs.getTxStoreKey());//店面账号
        
        //组装平台商品信息
        List<Map<String, Object>> platFormInfo = new ArrayList<Map<String,Object>>();
        Map<String, Object> platFormInfoData = new HashMap<String, Object>();
        List<GfsOrderDetail> detailList = gfs.getListGfsOrderDetail();
        if(CollectionUtils.isNotEmpty(detailList)){
            for(GfsOrderDetail detail : detailList){
                platFormInfoData.put("itemName", detail.getItemName());//平台商品名称
                platFormInfoData.put("itemId", detail.getItemId());//平台商品ID
                platFormInfoData.put("quantity", detail.getQuantity());//数量
                platFormInfoData.put("transactionPrice", detail.getTransactionPrice());//商品总价值
                platFormInfoData.put("itemDescription", detail.getItemDescription());//商品描述
                platFormInfo.add(platFormInfoData);
            }
        }
        data.put("platFormInfo", platFormInfo);
        
        return data;
   }
}
